├── images ├── 404.png ├── fish.png ├── totop.png ├── avatar.jpg ├── house1.png ├── house2.png ├── page_background.jpg ├── heart.svg ├── gitment-github-icon.svg ├── search.svg └── github.svg ├── config.json ├── LICENSE ├── server └── gh-oauth-server.php ├── issue_per_label.html ├── css ├── home.css ├── common.css └── gitment.css ├── index.html ├── 404.html ├── content.html ├── api.html ├── README.md ├── README_en.md └── js ├── typed.js └── gitblog.js /images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imuncle/gitblog/HEAD/images/404.png -------------------------------------------------------------------------------- /images/fish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imuncle/gitblog/HEAD/images/fish.png -------------------------------------------------------------------------------- /images/totop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imuncle/gitblog/HEAD/images/totop.png -------------------------------------------------------------------------------- /images/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imuncle/gitblog/HEAD/images/avatar.jpg -------------------------------------------------------------------------------- /images/house1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imuncle/gitblog/HEAD/images/house1.png -------------------------------------------------------------------------------- /images/house2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imuncle/gitblog/HEAD/images/house2.png -------------------------------------------------------------------------------- /images/page_background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imuncle/gitblog/HEAD/images/page_background.jpg -------------------------------------------------------------------------------- /images/heart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/gitment-github-icon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "imuncle", 3 | "repo": "gitblog", 4 | "client_id": "4148cca0f91e524d1a42", 5 | "client_secret": "637c2c993cccf79c51a0a215f538932edfdcb9b0", 6 | "title": "Gitblog", 7 | "instruction": "基于GitHub issue的个人博客模板", 8 | "server_link": "http://119.23.8.25/gh-oauth-server.php", 9 | "filter": { 10 | "creator": "all", 11 | "state": "open" 12 | }, 13 | "menu": { 14 | "首页":"./" 15 | }, 16 | "friends": { 17 | "imuncle" : "https://imuncle.github.io" 18 | }, 19 | "icons": { 20 | "Github" : { 21 | "icon_src" : "images/github.svg", 22 | "href" : "https://github.com/imuncle/gitblog", 23 | "hidden_img" : null, 24 | "width" : 0 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /images/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 big_uncle 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /server/gh-oauth-server.php: -------------------------------------------------------------------------------- 1 | array( 12 | 'method' => 'POST', 13 | 'header' => 'Content-type:application/x-www-form-urlencoded', 14 | 'content' => $postdata, 15 | 'timeout' => 15 * 60 // 超时时间(单位:s) 16 | ) 17 | ); 18 | $context = stream_context_create($options); 19 | $result = file_get_contents($url, false, $context); 20 | return $result; 21 | } 22 | 23 | $code = $_GET['code']; 24 | $redirect_url = $_GET['redirect_url']; 25 | $client_id = $_GET['client_id']; 26 | $client_secret = $_GET['client_secret']; 27 | 28 | $post_data = array( 29 | 'client_id' => $client_id, 30 | 'client_secret' => $client_secret, 31 | "code" => $code 32 | ); 33 | $html = send_post('https://github.com/login/oauth/access_token', $post_data); 34 | 35 | $data = explode("&", $html); 36 | $token = explode("=", $data[0]); 37 | ?> 38 | -------------------------------------------------------------------------------- /images/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /issue_per_label.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 22 |
23 |
24 |

25 |
26 | 27 |
28 |
29 |
30 |
    31 |
    32 |

    内容加载中...

    33 |
    34 |
35 |
36 |
37 | FEATURED TAGS 38 |
39 |
40 |
41 |
42 |
43 | 44 |
45 |
46 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /css/home.css: -------------------------------------------------------------------------------- 1 | .page_header{ 2 | width:100%; 3 | height:70vh; 4 | position: relative; 5 | background:url('../images/page_background.jpg') no-repeat 5% 60%; 6 | } 7 | .navi-button { 8 | font-size: .8rem; 9 | color: #7f8c8d; 10 | border: 1px solid rgba(127,140,141,0.6); 11 | line-height: 35px; 12 | border-radius: 4px; 13 | display: block; 14 | padding: 0 15px; 15 | right: 15px; 16 | top: 15px; 17 | cursor: pointer; 18 | text-transform: uppercase; 19 | z-index: 99; 20 | transition: all .3s; 21 | } 22 | .author { 23 | background: #ecf0f1; 24 | text-align: center; 25 | height:30vh; 26 | } 27 | .head { 28 | display: inline-block; 29 | width: 130px; 30 | height: 130px; 31 | border-radius: 50%; 32 | padding: 3px; 33 | background: #fff; 34 | box-shadow: 0 0 5px #95a5a6; 35 | position: relative; 36 | top: -68px; 37 | opacity: 0; 38 | transform: translateY(-20px); 39 | transition: all 0.8s; 40 | } 41 | .name { 42 | top: -68px; 43 | position: relative; 44 | opacity: 0; 45 | transform: translateY(-20px); 46 | transition: all 0.8s; 47 | } 48 | 49 | 50 | .pagination { 51 | margin-bottom: 80px; 52 | padding-left: 0; 53 | } 54 | 55 | body { 56 | background: #2c3e50; 57 | } 58 | .main_content { 59 | opacity: 0; 60 | transform: translateY(-20px); 61 | transition: all 0.8s; 62 | margin: 72px auto 0 auto; 63 | padding: 0 36px; 64 | list-style: none; 65 | } 66 | .main_content>li { 67 | margin-bottom: 20px; 68 | } 69 | .main { 70 | width:100%; 71 | background:#ffffff; 72 | } 73 | .main_content>li p.date, .main_content>li h4.title { 74 | font-weight: bold; 75 | } 76 | .main_content>li h4.title { 77 | line-height: 1.5; 78 | margin: 10px 0; 79 | } 80 | .main_content>li h4.title a { 81 | color: #2c3e50; 82 | transition: color .3s; 83 | } 84 | a { 85 | text-decoration: none; 86 | color: #34495e; 87 | } 88 | .main_content>li .excerpt, .main_content>li .excerpt *, .main_content>li .no-title { 89 | font-size: .9rem; 90 | color: #7f8c8d; 91 | line-height: 1.5; 92 | margin: 0; 93 | } 94 | .main_content>li .meta { 95 | margin-top: 20px; 96 | border: 1px solid #ecf0f1; 97 | border-width: 1px 0; 98 | padding: 22px 10px; 99 | font-size: .75rem; 100 | color: #7f8c8d; 101 | } 102 | .main_content>li .meta>li { 103 | margin-right: 22px; 104 | display: inline-block; 105 | } 106 | .main_content li > p { 107 | margin:0; 108 | } 109 | .main_content a { 110 | text-decoration: none; 111 | color: #34495e; 112 | } 113 | .issue{ 114 | overflow: hidden; 115 | text-overflow: ellipsis; 116 | display: -webkit-box; 117 | -webkit-line-clamp: 6; 118 | -webkit-box-orient: vertical; 119 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 22 |
23 | 24 |
25 |
26 | 27 |
28 |

29 |

30 |

I am today!

31 |
32 |
33 |
34 |
    35 |
    36 |

    内容加载中...

    37 |
    38 |
39 |
40 |
41 | FEATURED TAGS 42 |
43 |
44 |
45 |
46 |
47 | 48 |
49 | 53 |
54 | 55 | 56 | 57 | 58 | 77 | -------------------------------------------------------------------------------- /css/common.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | background: #2c3e50; 3 | padding: 50px 15px; 4 | width: 100%; 5 | bottom:0; 6 | } 7 | .navi-button { 8 | font-size: .8rem; 9 | color: #7f8c8d; 10 | border: 1px solid rgba(127,140,141,0.6); 11 | line-height: 35px; 12 | border-radius: 4px; 13 | display: block; 14 | padding: 0 15px; 15 | position: fixed; 16 | right: 15px; 17 | top: 15px; 18 | cursor: pointer; 19 | text-transform: uppercase; 20 | z-index: 99; 21 | transform: translateX(0); 22 | transition: all 0.4s; 23 | } 24 | .main-navication li { 25 | list-style: none; 26 | padding-left: 10px; 27 | } 28 | .main { 29 | transform: translateX(0); 30 | min-height: 100vh; 31 | transition: all 0.4s; 32 | } 33 | .main-navication { 34 | margin: 0; 35 | padding: 30px 0 0; 36 | background: #2c3e50; 37 | width: 150px; 38 | position: fixed; 39 | right: 0; 40 | top: 0; 41 | bottom: 0; 42 | opacity:0; 43 | transition: all 0.4s; 44 | overflow: auto; 45 | } 46 | .main-navication a, .main-navication a:visited { 47 | display: block; 48 | padding: 0 15px; 49 | color: white; 50 | text-decoration: none; 51 | } 52 | .main-navication a:hover { 53 | display: block; 54 | padding: 0 15px; 55 | color: white; 56 | } 57 | .main-navication span { 58 | font-size: 12px; 59 | line-height: 48px; 60 | display: block; 61 | opacity: 0; 62 | transform: translateX(-50px); 63 | transition: all 0.4s; 64 | } 65 | ul.pagination { 66 | display: inline-block; 67 | padding: 0; 68 | margin: 0; 69 | } 70 | ul.pagination li {display: inline;} 71 | ul.pagination li a { 72 | color: black; 73 | float: left; 74 | text-decoration: none; 75 | border:transparent; 76 | } 77 | ul.pagination li a.active { 78 | background-color: #ddd; 79 | color: white; 80 | pointer-events:none; 81 | } 82 | ul.pagination li a:hover:not(.active) {background-color: #ddd;} 83 | .post-tags { 84 | margin-top: 40px; 85 | text-align: center; 86 | } 87 | .post-tags a, .post-tags a:hover { 88 | display: inline-block; 89 | margin-right: 10px; 90 | font-size: 13px; 91 | overflow-wrap: break-word; 92 | word-wrap: break-word; 93 | background-color: transparent; 94 | color: #555; 95 | text-decoration: none; 96 | outline: none; 97 | border-bottom: 1px solid #999; 98 | cursor: pointer; 99 | } 100 | .Totop { 101 | position: fixed; 102 | right: 20px; 103 | bottom: 50px; 104 | display: block; 105 | width: 42px; 106 | height: 42px; 107 | opacity: 0; 108 | cursor: pointer; 109 | transform: translateY(0px); 110 | transition: all 0.4s; 111 | } 112 | .search { 113 | opacity: 0.6; 114 | position: fixed; 115 | right: 20px; 116 | top: 60px; 117 | cursor: pointer; 118 | z-index: 99; 119 | width: 35px; 120 | transition: all 0.4s; 121 | } 122 | .search-input { 123 | width: 42px; 124 | height: 42px; 125 | padding-left: 15px; 126 | border-radius: 42px; 127 | border: 1px solid rgba(127,140,141,0.6); 128 | background: white; 129 | outline: none; 130 | position: relative; 131 | transition: all 0.4s; 132 | position: fixed; 133 | right: 10px; 134 | top: 57px; 135 | z-index: -1; 136 | } 137 | .tags { 138 | margin-top:10px 139 | } 140 | .tags a , .tags a:hover{ 141 | display: inline-block; 142 | border: 1px solid rgba(255,255,255,.8); 143 | border-radius: 999em; 144 | padding: 0 10px; 145 | line-height:24px; 146 | font-size: 12px; 147 | text-decoration: none; 148 | margin-bottom: 6px; 149 | margin-right:5px; 150 | color:#bfbfbf; 151 | border-color:#bfbfbf 152 | } -------------------------------------------------------------------------------- /404.html: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | permalink: /404.html 4 | 5 | --- 6 | 7 | 8 | 9 | 10 | 404 Not Found 11 | 12 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | 25 |
26 |
27 | 28 |


29 | 回到首页 30 |
31 | 32 | 33 | 97 | 98 | -------------------------------------------------------------------------------- /content.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 22 |
23 |
24 |

25 |
26 | 27 |
28 |
29 |
30 |
内容加载中...
31 | 32 |
33 |
34 | 条评论 35 |
36 |
37 |
    38 |
    39 |
    40 | 41 |
    42 |
    43 |
    44 |
    45 |
    46 |
    47 | 51 | 52 |
    53 |
    54 |
    55 | 56 |
    57 |
    58 |
    (没有预览)
    59 |
    60 |
    61 |
    62 | 68 |
    69 |
    70 |
    71 |
    72 | 76 |
    77 | 78 | 79 | 80 | 81 | 82 | 92 | -------------------------------------------------------------------------------- /api.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | API请求 5 | 6 | 7 | 8 |
    
      9 |     
     10 | 
     11 | 
     12 | 
    
    
    --------------------------------------------------------------------------------
    /README.md:
    --------------------------------------------------------------------------------
      1 | # gitblog
      2 | 这是一个极轻量级的,基于git issue的个人博客模板,非常适合于想在GitHub pages上搭建个人博客的人。
      3 | 
      4 | [示例页面](https://imuncle.github.io/gitblog)
      5 | 
      6 | [English](README_en.md)
      7 | 
      8 | ## 现有功能
      9 | - [x] 发表文章
     10 | - [x] 文章评论
     11 | - [x] 文章、评论分页
     12 | - [x] 文章设置标签
     13 | - [x] 文章搜索功能
     14 | - [x] 文章、评论点赞功能(不能取消点赞 :stuck_out_tongue_winking_eye:
     15 | - [x] 博客API接口,可输出`json`格式信息,方便用户进行开发客户端等操作。具体接口使用见说明底部。
     16 | - [x] 可根据文章作者和文章状态(close或open)筛选文章,暂不支持多人筛选
     17 | 
     18 | 博客本身没有发表文章的接口,而是在GitHub的issue页面直接new issue。
     19 | 
     20 | 评论功能参考了[Gitment](https://github.com/imsun/gitment),借用了Gitment的css样式,重写了JavaScript逻辑。评论功能基于GitHub的issue,支持Markdown语法,支持@功能,支持点赞功能。
     21 | 
     22 | 可以在GitHub上为每个文章指定标签label。
     23 | 
     24 | 404页面模仿了GitHub自己的404页面,可点击[这里](https://imuncle.github.io/anything)查看404页面示例。
     25 | 
     26 | ## 如何开始
     27 | 
     28 | ### 复制该仓库
     29 | 最快捷的方法就是直接**Fork**这个repo,修改仓库名为`username.github.io`格式,然后稍微配置一下就能直接使用了。
     30 | 
     31 | 第二种办法就是clone仓库
     32 | 
     33 | ```git
     34 | git clone "https:/github.com/imuncle/gitblog"
     35 | ```
     36 | 
     37 | ### 申请GitHub OAuth APP
     38 | 点击[这里](https://github.com/settings/applications/new)申请。
     39 | 
     40 | 注意申请时的**callback URL**一定要填写正确。一般就写自己网站的首页就行,比如https://imuncle.github.io 。
     41 | 
     42 | 申请完毕后会拿到对应的唯一的**client_id**和**client_secret**,这两个字符串在后面的配置中会使用到。
     43 | 
     44 | ## 个性化定制
     45 | ### 基本配置
     46 | 修改**config.json**:
     47 | ```js
     48 | {
     49 |     "name": "your github username",
     50 |     "repo": "your github reponame",
     51 |     "client_id": "your client_id here",
     52 |     "client_secret": "your client_secret here",
     53 |     "title": "add your title",
     54 |     "instruction": "add your instruction",
     55 |     "server_link": "http://119.23.8.25/gh-oauth-server.php",
     56 |     "filter": {
     57 |         "creator": "all",	//@param: "all" or a username(eg. "imuncle")
     58 |         "state": "open"		//@param: "open", "close", "all"
     59 |     },
     60 |     "menu": {
     61 |         //add your menu items and URL here
     62 |         //example:
     63 |         //"Home" : "./",
     64 |         //"RSS" : "https://rsshub.app/github/issue/imuncle/imuncle.github.io",
     65 |         //"About me" : "content.html?id=41"
     66 |     },
     67 |     "friends": {
     68 |         //add your friends link here
     69 |         //example:
     70 |         //imuncle : "https://imuncle.github.io"
     71 |     },
     72 |     "icons": {
     73 |         //add your footer icons here
     74 |         //you can set a jump link or display an image
     75 |         //template :
     76 |         //"the title of the icon" : {
     77 |         //  "icon_src" : "the image of the icon",
     78 |         //  "href" : "the link you want to jump",
     79 |         //  "hidden_img" : "the image you want to show",
     80 |         //  "width" : the width of the hidden_img, this should be a number.(unit : px)
     81 |         //}
     82 |         //example :
     83 |         //"Github" : {
     84 |         //    "icon_src" : "images/github.svg",
     85 |         //    "href" : "https://github.com/imuncle",
     86 |         //    "hidden_img" : null,
     87 |         //    'width" : 0
     88 |         //}
     89 |     }
     90 | }
     91 | ```
     92 | 将自己的个人信息填写进去。
     93 | 
     94 | 选项|含义
     95 | :--:|:--:
     96 | name|填写你的GitHub用户名
     97 | repo|填写你的pages对应的仓库,一般是:用户名.github.io
     98 | client_id|填写你申请OAuth APP时拿到的client_id
     99 | client_secret|填写你申请OAuth APP时拿到的client_secret
    100 | title|填写你的个人网站的标题
    101 | instruction|填写你的个人网站的简介
    102 | server_link|填写你的服务端地址,~~若没有服务器可填写`http://119.23.8.25/gh-oauth-server.php`~~ 该服务器已停用
    103 | filter|填写issue筛选规则,可根据creator和issue state筛选
    104 | menu|填写右侧菜单中的名称和链接
    105 | friends|填写你的网站的友链,若没有则不填写
    106 | icons|填写网站页脚的图标信息,若没有则不填写
    107 | 
    108 | 上面的server_link是服务端的地址,,因为访问用户的access_token必须通过服务端访问,详情可见[这篇文章](https://imuncle.github.io/content.html?id=22)。这个服务端使用PHP编写,只负责请求用户的access_token,不会存储任何数据。详见[源代码](https://github.com/imuncle/gitblog/blob/master/server/gh-oauth-server.php)。
    109 | 
    110 | 如果你有服务器,那么你可以使用该PHP代码自己配置服务端,将**server_link**写为自己的服务端地址。
    111 | 
    112 | ### 动态打字配置
    113 | 网站首页有一个动态打字的效果,这里参考的是[type.js](https://github.com/mattboldt/typed.js)项目,配置地方在**index.html**中。
    114 | 
    115 | 找到如下代码(在尾部):
    116 | ```javascript
    117 | $("#changerificwordspanid").typed({
    118 |     strings: ["good", "happy", "healthy", "tall"],
    119 |     typeSpeed: 100,
    120 |     startDelay: 10,
    121 |     showCursor: true,
    122 |     shuffle: true,
    123 |     loop:true
    124 | });
    125 | ```
    126 | 可以更改`strings`来更改单词。更多的配置选项请参考[原项目](https://github.com/mattboldt/typed.js)。
    127 | 
    128 | ### 图片更改
    129 | 图片全部都存储在**images**文件夹中。
    130 | 
    131 | 图片名称|含义
    132 | :--:|:--:
    133 | 404.png|404页面
    134 | avatar.jpg|网站图标
    135 | fish.png|404页面
    136 | github.svg|GitHub图标
    137 | house1.png|404页面
    138 | house2.png|404页面
    139 | page_backfround.jpg|首页的背景图
    140 | search.svg|右上角搜索图标
    141 | totop.png|右下角“回到顶部”按钮图标
    142 | 
    143 | 如果没有前端知识,建议更改图片时不要更改文件名。
    144 | 
    145 | ## API接口
    146 | API接口的实现见[api.html](https://github.com/imuncle/gitblog/blob/master/api.html),通过访问该文件获取信息,使用url参数指定获取的信息内容。具体的用法如下。
    147 | 
    148 | ### 获取菜单信息
    149 | ```javascript
    150 | $.ajax({
    151 |     type: 'get',
    152 |     headers: {
    153 |         Accept: 'application/json',
    154 |     },
    155 |     url: 'your domain name' + 'api.html?menu=menu',
    156 |     success: function(data) {
    157 |         //your code here
    158 |     }
    159 | });
    160 | ```
    161 | 
    162 | 返回的数据格式如下:
    163 | ```json
    164 | [
    165 | 	{
    166 | 		"name": "首页",
    167 | 		"url": "./"
    168 | 	},
    169 | 	{
    170 | 		"name": "机器学习",
    171 | 		"url": "issue_per_label.html?label=AI"
    172 | 	},
    173 | 	{
    174 | 		"name": "小项目",
    175 | 		"url": "issue_per_label.html?label=Project"
    176 | 	},
    177 | 	{
    178 | 		"name": "RM比赛",
    179 | 		"url": "issue_per_label.html?label=RM"
    180 | 	},
    181 | 	{
    182 | 		"name": "ROS学习",
    183 | 		"url": "issue_per_label.html?label=ROS"
    184 | 	},
    185 | 	{
    186 | 		"name": "小工具",
    187 | 		"url": "issue_per_label.html?label=tools"
    188 | 	},
    189 | 	{
    190 | 		"name": "网页开发",
    191 | 		"url": "issue_per_label.html?label=web"
    192 | 	},
    193 | 	{
    194 | 		"name": "其他",
    195 | 		"url": "issue_per_label.html?label=other"
    196 | 	},
    197 | 	{
    198 | 		"name": "灵感想法",
    199 | 		"url": "https://imuncle.github.io/timeline"
    200 | 	},
    201 | 	{
    202 | 		"name": "关于我",
    203 | 		"url": "content.html?id=41"
    204 | 	}
    205 | ]
    206 | ```
    207 | 
    208 | ### 获取文章列表
    209 | 获取文章列表分为三种模式:一种是无筛选的普通模式,一种是按标签(label)筛选的标签模式,一种是按搜索内容筛选的搜索模式。三种模式都支持分页模式。
    210 | ```javascript
    211 | var request_url = 'your domain name' + 'api.html?';
    212 | request_url += 'page=1';    //普通模式
    213 | request_url += 'label=RM&page=1';   //标签模式
    214 | request_url += 'q=姿态解析&page=1'; //搜索模式
    215 | $.ajax({
    216 |     type: 'get',
    217 |     headers: {
    218 |         Accept: 'application/json',
    219 |     },
    220 |     url: request_url,
    221 |     success: function(data) {
    222 |         //your code here
    223 |     }
    224 | });
    225 | ```
    226 | > 注:以上代码中`page`参数均为可选。
    227 | 
    228 | 返回的数据格式如下:
    229 | ```json
    230 | {
    231 | 	"page": 4,
    232 | 	"page_num": 8,
    233 | 	"article": [
    234 | 		{
    235 | 			"id": 48,
    236 | 			"time": "2019/4/7 23:00:49",
    237 | 			"title": "STM32 flash读写",
    238 | 			"author": "imuncle",
    239 | 			"content": "文章内容太多了,此处省略...",
    240 | 			"labels": [
    241 | 				{
    242 | 					"name": "RM"
    243 | 				}
    244 | 			]
    245 | 		},
    246 | 		{
    247 | 			"id": 47,
    248 | 			"time": "2019/4/5 01:58:44",
    249 | 			"title": "WS2811驱动",
    250 | 			"author": "imuncle",
    251 | 			"content": "文章内容太多了,此处省略...",
    252 | 			"labels": [
    253 | 				{
    254 | 					"name": "RM"
    255 | 				}
    256 | 			]
    257 | 		},
    258 | 		{
    259 | 			"id": 46,
    260 | 			"time": "2019/4/1 18:57:58",
    261 | 			"title": "DS18B20温度传感器数据读取",
    262 | 			"author": "imuncle",
    263 | 			"content": "文章内容太多了,此处省略...",
    264 | 			"labels": [
    265 | 				{
    266 | 					"name": "other"
    267 | 				}
    268 | 			]
    269 | 		},
    270 | 		{
    271 | 			"id": 45,
    272 | 			"time": "2019/4/1 18:01:15",
    273 | 			"title": "HAL库实现us级延时",
    274 | 			"author": "imuncle",
    275 | 			"content": "文章内容太多了,此处省略...",
    276 | 			"labels": [
    277 | 				{
    278 | 					"name": "other"
    279 | 				}
    280 | 			]
    281 | 		},
    282 | 		{
    283 | 			"id": 44,
    284 | 			"time": "2019/4/1 10:00:40",
    285 | 			"title": "MPU9250六轴算法",
    286 | 			"author": "imuncle",
    287 | 			"content": "文章内容太多了,此处省略...",
    288 | 			"labels": [
    289 | 				{
    290 | 					"name": "RM"
    291 | 				}
    292 | 			]
    293 | 		},
    294 | 		{
    295 | 			"id": 43,
    296 | 			"time": "2019/3/30 09:19:57",
    297 | 			"title": "MATLAB串口通信GUI程序",
    298 | 			"author": "imuncle",
    299 | 			"content": "文章内容太多了,此处省略...",
    300 | 			"labels": [
    301 | 				{
    302 | 					"name": "other"
    303 | 				}
    304 | 			]
    305 | 		},
    306 | 		{
    307 | 			"id": 42,
    308 | 			"time": "2019/3/24 12:01:25",
    309 | 			"title": "网站搜索功能",
    310 | 			"author": "imuncle",
    311 | 			"content": "文章内容太多了,此处省略...",
    312 | 			"labels": [
    313 | 				{
    314 | 					"name": "web"
    315 | 				}
    316 | 			]
    317 | 		},
    318 | 		{
    319 | 			"id": 40,
    320 | 			"time": "2019/3/19 15:19:52",
    321 | 			"title": "RM2018的奋斗",
    322 | 			"author": "imuncle",
    323 | 			"content": "文章内容太多了,此处省略... ",
    324 | 			"labels": [
    325 | 				{
    326 | 					"name": "RM"
    327 | 				}
    328 | 			]
    329 | 		},
    330 | 		{
    331 | 			"id": 39,
    332 | 			"time": "2019/3/18 18:03:35",
    333 | 			"title": "MPU9250姿态解析",
    334 | 			"author": "imuncle",
    335 | 			"content": "文章内容太多了,此处省略...",
    336 | 			"labels": [
    337 | 				{
    338 | 					"name": "RM"
    339 | 				}
    340 | 			]
    341 | 		},
    342 | 		{
    343 | 			"id": 38,
    344 | 			"time": "2019/3/10 19:03:28",
    345 | 			"title": "生成漂亮的代码分享图",
    346 | 			"author": "imuncle",
    347 | 			"content": "文章内容太多了,此处省略...",
    348 | 			"labels": [
    349 | 				{
    350 | 					"name": "tools"
    351 | 				}
    352 | 			]
    353 | 		}
    354 | 	]
    355 | }
    356 | ```
    357 | > 注:默认一页显示10篇文章
    358 | 
    359 | ### 获取文章内容
    360 | 这是获取文章的详细内容。**注意**,这里返回的是**HTML格式**的文章内容,而`获取文章列表`拿到的是**Markdown格式**的文章内容。使用方法如下:
    361 | ```javascript
    362 | $.ajax({
    363 |     type: 'get',
    364 |     headers: {
    365 |         Accept: 'application/json',
    366 |     },
    367 |     url: 'your domain name' + 'api.html?id=1',
    368 |     success: function(data) {
    369 |         //your code here
    370 |     }
    371 | });
    372 | ```
    373 | 
    374 | 返回的数据格式如下:
    375 | ```json
    376 | {
    377 | 	"title": "博客搭建过程",
    378 | 	"time": "2019/2/5 16:33:06",
    379 | 	"content": "文章内容太多了,此处省略...",
    380 | 	"labels": [
    381 | 		{
    382 | 			"name": "web"
    383 | 		}
    384 | 	],
    385 | 	"like": 0
    386 | }
    387 | ```
    388 | 
    389 | ## 依赖
    390 | * [gitment](https://github.com/imsun/gitment)
    391 | * [MathJax](https://www.mathjax.org/)
    392 | * [jQuery](http://www.jquery.org/)
    393 | * [Bootstrap](http://www.getbootstrap.com/)
    394 | * [type.js](https://github.com/mattboldt/typed.js)
    395 | 
    396 | 欢迎提issue,也欢迎PR~
    397 | 
    398 | ## 许可
    399 | MIT LICENSE
    400 | 
    
    
    --------------------------------------------------------------------------------
    /README_en.md:
    --------------------------------------------------------------------------------
      1 | # gitblog
      2 | This is a very small personal blog template bsaed on git issues for anyone who wants to build a personal blog on GitHub pages.
      3 | 
      4 | [Demo page](https://imuncle.github.io/gitblog)
      5 | 
      6 | [中文](README.md)
      7 | 
      8 | # Functions
      9 | - [x] Publish an article
     10 | - [x] Article comments
     11 | - [x] Set labels for article
     12 | - [x] Search for aticle
     13 | - [x] Like an article or comment
     14 | - [x] API. It can output 'json' format information. Using methods are at the bottom of README.
     15 | - [x] Issue Filter. You can filter your issues by creator or issue state (open or close). Multi-creator filtering is currently not supported.
     16 | 
     17 | You can publish your article in Github issues page, just click 'New issue'.
     18 | 
     19 | The comments feature is referenced by [Gitment](https://github.com/imsun/gitment). I borrowed its css and rewrite the js doc.
     20 | 
     21 | You can set labels for each article in Github issues page.
     22 | 
     23 | ## How to Start
     24 | ### Get this repo
     25 | You can **Fork** or **clone** this repo. Then you can customize by yourself.
     26 | 
     27 | ### Get Github OAuth APP
     28 | Click [here](https://github.com/settings/applications/new) to get a Github OAuth APP. Be sure that the **callback URL** is your own home website, such as 'https://imuncle.github.io' .
     29 | 
     30 | You'll get **client_id** and **client_secret** finally.
     31 | 
     32 | ## Personalized customization
     33 | ### Basic configuration
     34 | In **config.json**:
     35 | ```js
     36 | {
     37 |     "name": "your github username",
     38 |     "repo": "your github reponame",
     39 |     "client_id": "your client_id here",
     40 |     "client_secret": "your client_secret here",
     41 |     "title": "add your title",
     42 |     "instruction": "add your instruction",
     43 |     "server_link": "http://119.23.8.25/gh-oauth-server.php",
     44 |     "filter": {
     45 |         "creator": "all",	//@param: "all" or a username(eg. "imuncle")
     46 |         "state": "open"		//@param: "open", "close", "all"
     47 |     },
     48 |     "menu": {
     49 |         //add your menu items and URL here
     50 | 		//example:
     51 | 		//"Home" : "./",
     52 |         //"RSS" : "https://rsshub.app/github/issue/imuncle/imuncle.github.io",
     53 |         //"About me" : "content.html?id=41"
     54 |     },
     55 |     "friends": {
     56 |         //add your friends link here
     57 |         //example:
     58 |         //imuncle : "https://imuncle.github.io"
     59 |     },
     60 |     "icons": {
     61 |         //add your footer icons here
     62 |         //you can set a jump link or display an image
     63 |         //template :
     64 |         //"the title of the icon" : {
     65 |         //  "icon_src" : "the image of the icon",
     66 |         //  "href" : "the link you want to jump",
     67 |         //  "hidden_img" : "the image you want to show",
     68 |         //  "width" : the width of the hidden_img, this should be a number.(unit : px)
     69 |         //}
     70 |         //example :
     71 |         //"Github" : {
     72 |         //    "icon_src" : "images/github.svg",
     73 |         //    "href" : "https://github.com/imuncle",
     74 |         //    "hidden_img" : null,
     75 |         //    'width" : 0
     76 |         //}
     77 |     }
     78 | }
     79 | ```
     80 | Add your own information into it.
     81 | 
     82 | Options|interpretation
     83 | :--:|:--:
     84 | name|Fill in your GitHub username
     85 | repo|Fill in your pages corresponding repository, which is generally: username.github.io
     86 | client_id|Fill in the "client id" you got when you applied for OAuth APP
     87 | client_secret|Fill in the "client secret" you got when applying for OAuth APP
     88 | title|Fill in the title of your personal website
     89 | instruction|Fill in the profile of your website
     90 | server_link|Fill in your server address
     91 | filter|Fill in the issue filter rule. You can filter your issues by creator or issue state (open or close).
     92 | menu|Fill in the names and links in the menu on the right
     93 | friends|Fill in the friendship chain of your website (optional)
     94 | icons|Fill in the informations of the icons that you want to show at the bottom (optional)
     95 | 
     96 | The server_link above is the address of the server, because the access_token of the accessing user must be accessed through the server. Details can be found in [this article] (https://imuncle.github.io/content.html?id=22). This server is written in PHP and is only responsible for requesting the user's access_token and does not store any data. See the [source code](https://github.com/imuncle/gitblog/blob/master/server/gh-oauth-server.php).
     97 | 
     98 | If you have a server, you can use the PHP code to configure the server yourself and write **server_link** as your server address.
     99 | 
    100 | ### Dynamic typing
    101 | You can see a dynamic typing effect in the home page in [demo page](https://imuncle.github.io). This is references by [type.js](https://github.com/mattboldt/typed.js). You can config it in **index.html**:
    102 | 
    103 | ```javascript
    104 | $("#changerificwordspanid").typed({
    105 |     strings: ["good", "happy", "healthy", "tall"],
    106 |     typeSpeed: 100,
    107 |     startDelay: 10,
    108 |     showCursor: true,
    109 |     shuffle: true,
    110 |     loop:true
    111 | });
    112 | ```
    113 | By changing the `strings`, you can make your own dynamic typing. For more information you can visit [type.js](https://github.com/mattboldt/typed.js).
    114 | 
    115 | ### Images
    116 | All the images are stored in **images** folder. You can change them at will.
    117 | 
    118 | ## API
    119 | The details of implementing can be found in [api.html](https://github.com/imuncle/gitblog/blob/master/api.html).
    120 | 
    121 | ### Get menu lists
    122 | ```javascript
    123 | $.ajax({
    124 |     type: 'get',
    125 |     headers: {
    126 |         Accept: 'application/json',
    127 |     },
    128 |     url: 'your domain name' + 'api.html?menu=menu',
    129 |     success: function(data) {
    130 |         //your code here
    131 |     }
    132 | });
    133 | ```
    134 | 
    135 | The format of json are as follows:
    136 | ```json
    137 | [
    138 | 	{
    139 | 		"name": "首页",
    140 | 		"url": "./"
    141 | 	},
    142 | 	{
    143 | 		"name": "机器学习",
    144 | 		"url": "issue_per_label.html?label=AI"
    145 | 	},
    146 | 	{
    147 | 		"name": "小项目",
    148 | 		"url": "issue_per_label.html?label=Project"
    149 | 	},
    150 | 	{
    151 | 		"name": "RM比赛",
    152 | 		"url": "issue_per_label.html?label=RM"
    153 | 	},
    154 | 	{
    155 | 		"name": "ROS学习",
    156 | 		"url": "issue_per_label.html?label=ROS"
    157 | 	},
    158 | 	{
    159 | 		"name": "小工具",
    160 | 		"url": "issue_per_label.html?label=tools"
    161 | 	},
    162 | 	{
    163 | 		"name": "网页开发",
    164 | 		"url": "issue_per_label.html?label=web"
    165 | 	},
    166 | 	{
    167 | 		"name": "其他",
    168 | 		"url": "issue_per_label.html?label=other"
    169 | 	},
    170 | 	{
    171 | 		"name": "灵感想法",
    172 | 		"url": "https://imuncle.github.io/timeline"
    173 | 	},
    174 | 	{
    175 | 		"name": "关于我",
    176 | 		"url": "content.html?id=41"
    177 | 	}
    178 | ]
    179 | ```
    180 | 
    181 | ### Get the article list
    182 | There are 3 modes:Normal Mode(no screening),Label Mode(screening by label),Search Mode(screening by search).
    183 | ```javascript
    184 | var request_url = 'your domain name' + 'api.html?';
    185 | request_url += 'page=1';    //Normal Mode
    186 | request_url += 'label=RM&page=1';   //Label Mode
    187 | request_url += 'q=姿态解析&page=1'; //Search Mode
    188 | $.ajax({
    189 |     type: 'get',
    190 |     headers: {
    191 |         Accept: 'application/json',
    192 |     },
    193 |     url: request_url,
    194 |     success: function(data) {
    195 |         //your code here
    196 |     }
    197 | });
    198 | ```
    199 | > Parameters of 'page' in the above code are optional.
    200 | 
    201 | The format of json are as follows:
    202 | ```json
    203 | {
    204 | 	"page": 4,
    205 | 	"page_num": 8,
    206 | 	"article": [
    207 | 		{
    208 | 			"id": 48,
    209 | 			"time": "2019/4/7 23:00:49",
    210 | 			"title": "STM32 flash读写",
    211 | 			"author": "imuncle",
    212 | 			"content": "文章内容太多了,此处省略...",
    213 | 			"labels": [
    214 | 				{
    215 | 					"name": "RM"
    216 | 				}
    217 | 			]
    218 | 		},
    219 | 		{
    220 | 			"id": 47,
    221 | 			"time": "2019/4/5 01:58:44",
    222 | 			"title": "WS2811驱动",
    223 | 			"author": "imuncle",
    224 | 			"content": "文章内容太多了,此处省略...",
    225 | 			"labels": [
    226 | 				{
    227 | 					"name": "RM"
    228 | 				}
    229 | 			]
    230 | 		},
    231 | 		{
    232 | 			"id": 46,
    233 | 			"time": "2019/4/1 18:57:58",
    234 | 			"title": "DS18B20温度传感器数据读取",
    235 | 			"author": "imuncle",
    236 | 			"content": "文章内容太多了,此处省略...",
    237 | 			"labels": [
    238 | 				{
    239 | 					"name": "other"
    240 | 				}
    241 | 			]
    242 | 		},
    243 | 		{
    244 | 			"id": 45,
    245 | 			"time": "2019/4/1 18:01:15",
    246 | 			"title": "HAL库实现us级延时",
    247 | 			"author": "imuncle",
    248 | 			"content": "文章内容太多了,此处省略...",
    249 | 			"labels": [
    250 | 				{
    251 | 					"name": "other"
    252 | 				}
    253 | 			]
    254 | 		},
    255 | 		{
    256 | 			"id": 44,
    257 | 			"time": "2019/4/1 10:00:40",
    258 | 			"title": "MPU9250六轴算法",
    259 | 			"author": "imuncle",
    260 | 			"content": "文章内容太多了,此处省略...",
    261 | 			"labels": [
    262 | 				{
    263 | 					"name": "RM"
    264 | 				}
    265 | 			]
    266 | 		},
    267 | 		{
    268 | 			"id": 43,
    269 | 			"time": "2019/3/30 09:19:57",
    270 | 			"title": "MATLAB串口通信GUI程序",
    271 | 			"author": "imuncle",
    272 | 			"content": "文章内容太多了,此处省略...",
    273 | 			"labels": [
    274 | 				{
    275 | 					"name": "other"
    276 | 				}
    277 | 			]
    278 | 		},
    279 | 		{
    280 | 			"id": 42,
    281 | 			"time": "2019/3/24 12:01:25",
    282 | 			"title": "网站搜索功能",
    283 | 			"author": "imuncle",
    284 | 			"content": "文章内容太多了,此处省略...",
    285 | 			"labels": [
    286 | 				{
    287 | 					"name": "web"
    288 | 				}
    289 | 			]
    290 | 		},
    291 | 		{
    292 | 			"id": 40,
    293 | 			"time": "2019/3/19 15:19:52",
    294 | 			"title": "RM2018的奋斗",
    295 | 			"author": "imuncle",
    296 | 			"content": "文章内容太多了,此处省略... ",
    297 | 			"labels": [
    298 | 				{
    299 | 					"name": "RM"
    300 | 				}
    301 | 			]
    302 | 		},
    303 | 		{
    304 | 			"id": 39,
    305 | 			"time": "2019/3/18 18:03:35",
    306 | 			"title": "MPU9250姿态解析",
    307 | 			"author": "imuncle",
    308 | 			"content": "文章内容太多了,此处省略...",
    309 | 			"labels": [
    310 | 				{
    311 | 					"name": "RM"
    312 | 				}
    313 | 			]
    314 | 		},
    315 | 		{
    316 | 			"id": 38,
    317 | 			"time": "2019/3/10 19:03:28",
    318 | 			"title": "生成漂亮的代码分享图",
    319 | 			"author": "imuncle",
    320 | 			"content": "文章内容太多了,此处省略...",
    321 | 			"labels": [
    322 | 				{
    323 | 					"name": "tools"
    324 | 				}
    325 | 			]
    326 | 		}
    327 | 	]
    328 | }
    329 | ```
    330 | > In default, each page displays 10 articles.
    331 | 
    332 | ### Get content of an article
    333 | **Attention**: This returns the article content in **HTML format**, while 'Get the article list' gets the article content in **Markdown format**.
    334 | ```javascript
    335 | $.ajax({
    336 |     type: 'get',
    337 |     headers: {
    338 |         Accept: 'application/json',
    339 |     },
    340 |     url: 'your domain name' + 'api.html?id=1',
    341 |     success: function(data) {
    342 |         //your code here
    343 |     }
    344 | });
    345 | ```
    346 | 
    347 | The format of json are as follows:
    348 | ```json
    349 | {
    350 | 	"title": "博客搭建过程",
    351 | 	"time": "2019/2/5 16:33:06",
    352 | 	"content": "文章内容太多了,此处省略...",
    353 | 	"labels": [
    354 | 		{
    355 | 			"name": "web"
    356 | 		}
    357 | 	],
    358 | 	"like": 0
    359 | }
    360 | ```
    361 | 
    362 | ### Dependence
    363 | * [gitment](https://github.com/imsun/gitment)
    364 | * [MathJax](https://www.mathjax.org/)
    365 | * [jQuery](http://www.jquery.org/)
    366 | * [Bootstrap](http://www.getbootstrap.com/)
    367 | * [type.js](https://github.com/mattboldt/typed.js)
    368 | 
    369 | ## LICENSE
    370 | MIT LICENSE
    371 | 
    
    
    --------------------------------------------------------------------------------
    /js/typed.js:
    --------------------------------------------------------------------------------
      1 | // The MIT License (MIT)
      2 | 
      3 | // Typed.js | Copyright (c) 2014 Matt Boldt | www.mattboldt.com
      4 | 
      5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
      6 | // of this software and associated documentation files (the "Software"), to deal
      7 | // in the Software without restriction, including without limitation the rights
      8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      9 | // copies of the Software, and to permit persons to whom the Software is
     10 | // furnished to do so, subject to the following conditions:
     11 | 
     12 | // The above copyright notice and this permission notice shall be included in
     13 | // all copies or substantial portions of the Software.
     14 | 
     15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     21 | // THE SOFTWARE.
     22 | 
     23 | 
     24 | 
     25 | 
     26 | ! function($) {
     27 | 
     28 | 	"use strict";
     29 | 
     30 | 	var Typed = function(el, options) {
     31 | 
     32 | 		// chosen element to manipulate text
     33 | 		this.el = $(el);
     34 | 
     35 | 		// options
     36 | 		this.options = $.extend({}, $.fn.typed.defaults, options);
     37 | 
     38 | 		// attribute to type into
     39 | 		this.isInput = this.el.is('input');
     40 | 		this.attr = this.options.attr;
     41 | 
     42 | 		// show cursor
     43 | 		this.showCursor = this.isInput ? false : this.options.showCursor;
     44 | 
     45 | 		// text content of element
     46 | 		this.elContent = this.attr ? this.el.attr(this.attr) : this.el.text();
     47 | 
     48 | 		// html or plain text
     49 | 		this.contentType = this.options.contentType;
     50 | 
     51 | 		// typing speed
     52 | 		this.typeSpeed = this.options.typeSpeed;
     53 | 
     54 | 		// add a delay before typing starts
     55 | 		this.startDelay = this.options.startDelay;
     56 | 
     57 | 		// backspacing speed
     58 | 		this.backSpeed = this.options.backSpeed;
     59 | 
     60 | 		// amount of time to wait before backspacing
     61 | 		this.backDelay = this.options.backDelay;
     62 | 
     63 | 		// div containing strings
     64 | 		this.stringsElement = this.options.stringsElement;
     65 | 
     66 | 		// input strings of text
     67 | 		this.strings = this.options.strings;
     68 | 
     69 | 		// character number position of current string
     70 | 		this.strPos = 0;
     71 | 
     72 | 		// current array position
     73 | 		this.arrayPos = 0;
     74 | 
     75 | 		// number to stop backspacing on.
     76 | 		// default 0, can change depending on how many chars
     77 | 		// you want to remove at the time
     78 | 		this.stopNum = 0;
     79 | 
     80 | 		// Looping logic
     81 | 		this.loop = this.options.loop;
     82 | 		this.loopCount = this.options.loopCount;
     83 | 		this.curLoop = 0;
     84 | 
     85 | 		// for stopping
     86 | 		this.stop = false;
     87 | 
     88 | 		// custom cursor
     89 | 		this.cursorChar = this.options.cursorChar;
     90 | 
     91 | 		// shuffle the strings
     92 | 		this.shuffle = this.options.shuffle;
     93 | 		// the order of strings
     94 | 		this.sequence = [];
     95 | 
     96 | 		// All systems go!
     97 | 		this.build();
     98 | 	};
     99 | 
    100 | 	Typed.prototype = {
    101 | 
    102 | 		constructor: Typed,
    103 | 
    104 | 		init: function() {
    105 | 			// begin the loop w/ first current string (global self.strings)
    106 | 			// current string will be passed as an argument each time after this
    107 | 			var self = this;
    108 | 			self.timeout = setTimeout(function() {
    109 | 				for (var i=0;i" + this.cursorChar + "");
    124 | 				this.el.after(this.cursor);
    125 | 			}
    126 | 			if (this.stringsElement) {
    127 | 				this.strings = [];
    128 | 				this.stringsElement.hide();
    129 | 				console.log(this.stringsElement.children());
    130 | 				var strings = this.stringsElement.children();
    131 | 				$.each(strings, function(key, value){
    132 | 					self.strings.push($(value).html());
    133 | 				});
    134 | 			}
    135 | 			this.init();
    136 | 		},
    137 | 
    138 | 		// pass current string state to each function, types 1 char per call
    139 | 		typewrite: function(curString, curStrPos) {
    140 | 			// exit when stopped
    141 | 			if (this.stop === true) {
    142 | 				return;
    143 | 			}
    144 | 
    145 | 			// varying values for setTimeout during typing
    146 | 			// can't be global since number changes each time loop is executed
    147 | 			var humanize = Math.round(Math.random() * (100 - 30)) + this.typeSpeed;
    148 | 			var self = this;
    149 | 
    150 | 			// ------------- optional ------------- //
    151 | 			// backpaces a certain string faster
    152 | 			// ------------------------------------ //
    153 | 			// if (self.arrayPos == 1){
    154 | 			//  self.backDelay = 50;
    155 | 			// }
    156 | 			// else{ self.backDelay = 500; }
    157 | 
    158 | 			// contain typing function in a timeout humanize'd delay
    159 | 			self.timeout = setTimeout(function() {
    160 | 				// check for an escape character before a pause value
    161 | 				// format: \^\d+ .. eg: ^1000 .. should be able to print the ^ too using ^^
    162 | 				// single ^ are removed from string
    163 | 				var charPause = 0;
    164 | 				var substr = curString.substr(curStrPos);
    165 | 				if (substr.charAt(0) === '^') {
    166 | 					var skip = 1; // skip atleast 1
    167 | 					if (/^\^\d+/.test(substr)) {
    168 | 						substr = /\d+/.exec(substr)[0];
    169 | 						skip += substr.length;
    170 | 						charPause = parseInt(substr);
    171 | 					}
    172 | 
    173 | 					// strip out the escape character and pause value so they're not printed
    174 | 					curString = curString.substring(0, curStrPos) + curString.substring(curStrPos + skip);
    175 | 				}
    176 | 
    177 | 				if (self.contentType === 'html') {
    178 | 					// skip over html tags while typing
    179 | 					var curChar = curString.substr(curStrPos).charAt(0)
    180 | 					if (curChar === '<' || curChar === '&') {
    181 | 						var tag = '';
    182 | 						var endTag = '';
    183 | 						if (curChar === '<') {
    184 | 							endTag = '>'
    185 | 						}
    186 | 						else {
    187 | 							endTag = ';'
    188 | 						}
    189 | 						while (curString.substr(curStrPos + 1).charAt(0) !== endTag) {
    190 | 							tag += curString.substr(curStrPos).charAt(0);
    191 | 							curStrPos++;
    192 | 							if (curStrPos + 1 > curString.length) { break; }
    193 | 						}
    194 | 						curStrPos++;
    195 | 						tag += endTag;
    196 | 					}
    197 | 				}
    198 | 
    199 | 				// timeout for any pause after a character
    200 | 				self.timeout = setTimeout(function() {
    201 | 					if (curStrPos === curString.length) {
    202 | 						// fires callback function
    203 | 						self.options.onStringTyped(self.arrayPos);
    204 | 
    205 | 						// is this the final string
    206 | 						if (self.arrayPos === self.strings.length - 1) {
    207 | 							// animation that occurs on the last typed string
    208 | 							self.options.callback();
    209 | 
    210 | 							self.curLoop++;
    211 | 
    212 | 							// quit if we wont loop back
    213 | 							if (self.loop === false || self.curLoop === self.loopCount)
    214 | 								return;
    215 | 						}
    216 | 
    217 | 						self.timeout = setTimeout(function() {
    218 | 							self.backspace(curString, curStrPos);
    219 | 						}, self.backDelay);
    220 | 
    221 | 					} else {
    222 | 
    223 | 						/* call before functions if applicable */
    224 | 						if (curStrPos === 0) {
    225 | 							self.options.preStringTyped(self.arrayPos);
    226 | 						}
    227 | 
    228 | 						// start typing each new char into existing string
    229 | 						// curString: arg, self.el.html: original text inside element
    230 | 						var nextString = curString.substr(0, curStrPos + 1);
    231 | 						if (self.attr) {
    232 | 							self.el.attr(self.attr, nextString);
    233 | 						} else {
    234 | 							if (self.isInput) {
    235 | 								self.el.val(nextString);
    236 | 							} else if (self.contentType === 'html') {
    237 | 								self.el.html(nextString);
    238 | 							} else {
    239 | 								self.el.text(nextString);
    240 | 							}
    241 | 						}
    242 | 
    243 | 						// add characters one by one
    244 | 						curStrPos++;
    245 | 						// loop the function
    246 | 						self.typewrite(curString, curStrPos);
    247 | 					}
    248 | 					// end of character pause
    249 | 				}, charPause);
    250 | 
    251 | 				// humanized value for typing
    252 | 			}, humanize);
    253 | 
    254 | 		},
    255 | 
    256 | 		backspace: function(curString, curStrPos) {
    257 | 			// exit when stopped
    258 | 			if (this.stop === true) {
    259 | 				return;
    260 | 			}
    261 | 
    262 | 			// varying values for setTimeout during typing
    263 | 			// can't be global since number changes each time loop is executed
    264 | 			var humanize = Math.round(Math.random() * (100 - 30)) + this.backSpeed;
    265 | 			var self = this;
    266 | 
    267 | 			self.timeout = setTimeout(function() {
    268 | 
    269 | 				// ----- this part is optional ----- //
    270 | 				// check string array position
    271 | 				// on the first string, only delete one word
    272 | 				// the stopNum actually represents the amount of chars to
    273 | 				// keep in the current string. In my case it's 14.
    274 | 				// if (self.arrayPos == 1){
    275 | 				//  self.stopNum = 14;
    276 | 				// }
    277 | 				//every other time, delete the whole typed string
    278 | 				// else{
    279 | 				//  self.stopNum = 0;
    280 | 				// }
    281 | 
    282 | 				if (self.contentType === 'html') {
    283 | 					// skip over html tags while backspacing
    284 | 					if (curString.substr(curStrPos).charAt(0) === '>') {
    285 | 						var tag = '';
    286 | 						while (curString.substr(curStrPos - 1).charAt(0) !== '<') {
    287 | 							tag -= curString.substr(curStrPos).charAt(0);
    288 | 							curStrPos--;
    289 | 							if (curStrPos < 0) { break; }
    290 | 						}
    291 | 						curStrPos--;
    292 | 						tag += '<';
    293 | 					}
    294 | 				}
    295 | 
    296 | 				// ----- continue important stuff ----- //
    297 | 				// replace text with base text + typed characters
    298 | 				var nextString = curString.substr(0, curStrPos);
    299 | 				if (self.attr) {
    300 | 					self.el.attr(self.attr, nextString);
    301 | 				} else {
    302 | 					if (self.isInput) {
    303 | 						self.el.val(nextString);
    304 | 					} else if (self.contentType === 'html') {
    305 | 						self.el.html(nextString);
    306 | 					} else {
    307 | 						self.el.text(nextString);
    308 | 					}
    309 | 				}
    310 | 
    311 | 				// if the number (id of character in current string) is
    312 | 				// less than the stop number, keep going
    313 | 				if (curStrPos > self.stopNum) {
    314 | 					// subtract characters one by one
    315 | 					curStrPos--;
    316 | 					// loop the function
    317 | 					self.backspace(curString, curStrPos);
    318 | 				}
    319 | 				// if the stop number has been reached, increase
    320 | 				// array position to next string
    321 | 				else if (curStrPos <= self.stopNum) {
    322 | 					self.arrayPos++;
    323 | 
    324 | 					if (self.arrayPos === self.strings.length) {
    325 | 						self.arrayPos = 0;
    326 | 
    327 | 						// Shuffle sequence again
    328 | 						if(self.shuffle) self.sequence = self.shuffleArray(self.sequence);
    329 | 
    330 | 						self.init();
    331 | 					} else
    332 | 						self.typewrite(self.strings[self.sequence[self.arrayPos]], curStrPos);
    333 | 				}
    334 | 
    335 | 				// humanized value for typing
    336 | 			}, humanize);
    337 | 
    338 | 		},
    339 | 		/**
    340 | 		 * Shuffles the numbers in the given array.
    341 | 		 * @param {Array} array
    342 | 		 * @returns {Array}
    343 | 		 */
    344 | 		shuffleArray: function(array) {
    345 | 			var tmp, current, top = array.length;
    346 | 			if(top) while(--top) {
    347 | 				current = Math.floor(Math.random() * (top + 1));
    348 | 				tmp = array[current];
    349 | 				array[current] = array[top];
    350 | 				array[top] = tmp;
    351 | 			}
    352 | 			return array;
    353 | 		},
    354 | 
    355 | 		// Start & Stop currently not working
    356 | 
    357 | 		// , stop: function() {
    358 | 		//     var self = this;
    359 | 
    360 | 		//     self.stop = true;
    361 | 		//     clearInterval(self.timeout);
    362 | 		// }
    363 | 
    364 | 		// , start: function() {
    365 | 		//     var self = this;
    366 | 		//     if(self.stop === false)
    367 | 		//        return;
    368 | 
    369 | 		//     this.stop = false;
    370 | 		//     this.init();
    371 | 		// }
    372 | 
    373 | 		// Reset and rebuild the element
    374 | 		reset: function() {
    375 | 			var self = this;
    376 | 			clearInterval(self.timeout);
    377 | 			var id = this.el.attr('id');
    378 | 			this.el.empty();
    379 | 			if (typeof this.cursor !== 'undefined') {
    380 |         this.cursor.remove();
    381 |       }
    382 | 			this.strPos = 0;
    383 | 			this.arrayPos = 0;
    384 | 			this.curLoop = 0;
    385 | 			// Send the callback
    386 | 			this.options.resetCallback();
    387 | 		}
    388 | 
    389 | 	};
    390 | 
    391 | 	$.fn.typed = function(option) {
    392 | 		return this.each(function() {
    393 | 			var $this = $(this),
    394 | 				data = $this.data('typed'),
    395 | 				options = typeof option == 'object' && option;
    396 | 			if (data) { data.reset(); }
    397 | 			$this.data('typed', (data = new Typed(this, options)));
    398 | 			if (typeof option == 'string') data[option]();
    399 | 		});
    400 | 	};
    401 | 
    402 | 	$.fn.typed.defaults = {
    403 | 		strings: ["These are the default values...", "You know what you should do?", "Use your own!", "Have a great day!"],
    404 | 		stringsElement: null,
    405 | 		// typing speed
    406 | 		typeSpeed: 0,
    407 | 		// time before typing starts
    408 | 		startDelay: 0,
    409 | 		// backspacing speed
    410 | 		backSpeed: 0,
    411 | 		// shuffle the strings
    412 | 		shuffle: false,
    413 | 		// time before backspacing
    414 | 		backDelay: 500,
    415 | 		// loop
    416 | 		loop: false,
    417 | 		// false = infinite
    418 | 		loopCount: false,
    419 | 		// show cursor
    420 | 		showCursor: true,
    421 | 		// character for cursor
    422 | 		cursorChar: "|",
    423 | 		// attribute to type (null == text)
    424 | 		attr: null,
    425 | 		// either html or text
    426 | 		contentType: 'html',
    427 | 		// call when done callback function
    428 | 		callback: function() {},
    429 | 		// starting callback function before each string
    430 | 		preStringTyped: function() {},
    431 | 		//callback for every typed string
    432 | 		onStringTyped: function() {},
    433 | 		// callback for reset
    434 | 		resetCallback: function() {}
    435 | 	};
    436 | 
    437 | 
    438 | }(window.jQuery);
    439 | 
    
    
    --------------------------------------------------------------------------------
    /css/gitment.css:
    --------------------------------------------------------------------------------
       1 | .gitment-container {
       2 |   font-family: sans-serif;
       3 |   font-size: 14px;
       4 |   line-height: 1.5;
       5 |   color: #333;
       6 |   word-wrap: break-word;
       7 | }
       8 | 
       9 | .gitment-container * {
      10 |   box-sizing: border-box;
      11 | }
      12 | 
      13 | .gitment-container *:disabled {
      14 |   cursor: not-allowed;
      15 | }
      16 | 
      17 | .gitment-container a,
      18 | .gitment-container a:visited {
      19 |   cursor: pointer;
      20 |   text-decoration: none;
      21 | }
      22 | 
      23 | .gitment-container a:hover {
      24 |   text-decoration: underline;
      25 | }
      26 | 
      27 | .gitment-container .gitment-hidden {
      28 |   display: none;
      29 | }
      30 | 
      31 | .gitment-container .gitment-spinner-icon {
      32 |   fill: #333;
      33 | 
      34 |   -webkit-animation: gitment-spin 1s steps(12) infinite;
      35 |   animation: gitment-spin 1s steps(12) infinite;
      36 | }
      37 | 
      38 | @-webkit-keyframes gitment-spin {
      39 |   100% {
      40 |     -webkit-transform: rotate(360deg);
      41 |     transform: rotate(360deg)
      42 |   }
      43 | }
      44 | 
      45 | @keyframes gitment-spin {
      46 |   100% {
      47 |     -webkit-transform: rotate(360deg);
      48 |     transform: rotate(360deg)
      49 |   }
      50 | }
      51 | 
      52 | .gitment-root-container {
      53 |   margin: 19px 0;
      54 | }
      55 | 
      56 | .gitment-header-container {
      57 |   margin: 19px 0;
      58 | }
      59 | 
      60 | .gitment-header-like-btn,
      61 | .gitment-comment-like-btn {
      62 |   cursor: pointer;
      63 | }
      64 | 
      65 | .gitment-comment-like-btn {
      66 |   float: right;
      67 | }
      68 | 
      69 | .gitment-comment-like-btn.liked {
      70 |   color: #F44336;
      71 | }
      72 | 
      73 | .gitment-header-like-btn svg {
      74 |   vertical-align: middle;
      75 |   height: 30px;
      76 | }
      77 | 
      78 | .gitment-comment-like-btn svg {
      79 |   vertical-align: middle;
      80 |   height: 20px;
      81 | }
      82 | 
      83 | .gitment-header-like-btn.liked svg,
      84 | .gitment-comment-like-btn.liked svg {
      85 |   fill: #F44336;
      86 | }
      87 | 
      88 | a.gitment-header-issue-link,
      89 | a.gitment-header-issue-link:visited {
      90 |   float: right;
      91 |   line-height: 30px;
      92 |   color: #666;
      93 | }
      94 | 
      95 | a.gitment-header-issue-link:hover {
      96 |   color: #666;
      97 | }
      98 | 
      99 | .gitment-comments-loading,
     100 | .gitment-comments-error,
     101 | .gitment-comments-empty {
     102 |   text-align: center;
     103 |   margin: 50px 0;
     104 | }
     105 | 
     106 | .gitment-comments-list {
     107 |   list-style: none;
     108 |   padding-left: 0;
     109 |   margin: 0 0 38px;
     110 | }
     111 | 
     112 | .gitment-comment,
     113 | .gitment-editor-container {
     114 |   position: relative;
     115 |   min-height: 60px;
     116 |   padding-left: 60px;
     117 |   margin: 19px 0;
     118 | }
     119 | 
     120 | .gitment-comment-avatar,
     121 | .gitment-editor-avatar {
     122 |   float: left;
     123 |   margin-left: -60px;
     124 | }
     125 | 
     126 | .gitment-comment-avatar,
     127 | .gitment-comment-avatar-img,
     128 | .gitment-comment-avatar,
     129 | .gitment-editor-avatar-img,
     130 | .gitment-editor-avatar svg {
     131 |   width: 44px;
     132 |   height: 44px;
     133 |   border-radius: 3px;
     134 | }
     135 | 
     136 | .gitment-editor-avatar .gitment-github-icon {
     137 |   fill: #fff;
     138 | }
     139 | 
     140 | .gitment-comment-main,
     141 | .gitment-editor-main {
     142 |   position: relative;
     143 |   border: 1px solid #CFD8DC;
     144 |   border-radius: 0;
     145 | }
     146 | 
     147 | .gitment-editor-main::before,
     148 | .gitment-editor-main::after,
     149 | .gitment-comment-main::before,
     150 | .gitment-comment-main::after {
     151 |   position: absolute;
     152 |   top: 11px;
     153 |   left: -16px;
     154 |   display: block;
     155 |   width: 0;
     156 |   height: 0;
     157 |   pointer-events: none;
     158 |   content: "";
     159 |   border-color: transparent;
     160 |   border-style: solid solid outset;
     161 | }
     162 | 
     163 | .gitment-editor-main::before,
     164 | .gitment-comment-main::before {
     165 |   border-width: 8px;
     166 |   border-right-color: #CFD8DC;
     167 | }
     168 | 
     169 | .gitment-editor-main::after,
     170 | .gitment-comment-main::after {
     171 |   margin-top: 1px;
     172 |   margin-left: 2px;
     173 |   border-width: 7px;
     174 |   border-right-color: #fff;
     175 | }
     176 | 
     177 | .gitment-comment-header {
     178 |   margin: 12px 15px;
     179 |   color: #666;
     180 |   background-color: #fff;
     181 |   border-radius: 3px;
     182 | }
     183 | 
     184 | .gitment-editor-header {
     185 |   padding: 0;
     186 |   margin: 0;
     187 |   border-bottom: 1px solid #CFD8DC;
     188 | }
     189 | 
     190 | a.gitment-comment-name,
     191 | a.gitment-comment-name:visited {
     192 |   font-weight: 600;
     193 |   color: #666;
     194 | }
     195 | 
     196 | .gitment-editor-tabs {
     197 |   margin-bottom: -1px;
     198 |   margin-left: -1px;
     199 | }
     200 | 
     201 | .gitment-editor-tab {
     202 |   display: inline-block;
     203 |   padding: 11px 12px;
     204 |   font-size: 14px;
     205 |   line-height: 20px;
     206 |   color: #666;
     207 |   text-decoration: none;
     208 |   background-color: transparent;
     209 |   border-width: 0 1px;
     210 |   border-style: solid;
     211 |   border-color: transparent;
     212 |   border-radius: 0;
     213 | 
     214 |   white-space: nowrap;
     215 |   cursor: pointer;
     216 |   user-select: none;
     217 | 
     218 |   outline: none;
     219 | }
     220 | 
     221 | .gitment-editor-tab.gitment-selected {
     222 |   color: #333;
     223 |   background-color: #fff;
     224 |   border-color: #CFD8DC;
     225 | }
     226 | 
     227 | .gitment-editor-login {
     228 |   float: right;
     229 |   margin-top: -30px;
     230 |   margin-right: 15px;
     231 | }
     232 | 
     233 | a.gitment-footer-project-link,
     234 | a.gitment-footer-project-link:visited,
     235 | a.gitment-editor-login-link,
     236 | a.gitment-editor-login-link:visited {
     237 |   color: #2196F3;
     238 | }
     239 | 
     240 | a.gitment-editor-logout-link,
     241 | a.gitment-editor-logout-link:visited {
     242 |   color: #666;
     243 | }
     244 | 
     245 | a.gitment-editor-logout-link:hover {
     246 |   color: #2196F3;
     247 |   text-decoration: none;
     248 | }
     249 | 
     250 | .gitment-comment-body {
     251 |   position: relative;
     252 |   margin: 12px 15px;
     253 |   overflow: hidden;
     254 |   border-radius: 3px;
     255 | }
     256 | 
     257 | .gitment-comment-body-folded {
     258 |   cursor: pointer;
     259 | }
     260 | 
     261 | .gitment-comment-body-folded::before {
     262 |   display: block !important;
     263 |   content: "";
     264 |   position: absolute;
     265 |   width: 100%;
     266 |   left: 0;
     267 |   top: 0;
     268 |   bottom: 50px;
     269 |   pointer-events: none;
     270 |   background: -webkit-linear-gradient(top, rgba(255, 255, 255, 0), rgba(255, 255, 255, .9));
     271 |   background: linear-gradient(180deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, .9));
     272 | }
     273 | 
     274 | .gitment-comment-body-folded::after {
     275 |   display: block !important;
     276 |   content: "Click to Expand" !important;
     277 |   text-align: center;
     278 |   color: #666;
     279 |   position: absolute;
     280 |   width: 100%;
     281 |   height: 50px;
     282 |   line-height: 50px;
     283 |   left: 0;
     284 |   bottom: 0;
     285 |   pointer-events: none;
     286 |   background: rgba(255, 255, 255, .9);
     287 | }
     288 | 
     289 | .gitment-editor-body {
     290 |   margin: 0;
     291 | }
     292 | 
     293 | .gitment-comment-body > *:first-child,
     294 | .gitment-editor-preview > *:first-child {
     295 |   margin-top: 0 !important;
     296 | }
     297 | 
     298 | .gitment-comment-body > *:last-child,
     299 | .gitment-editor-preview > *:last-child {
     300 |   margin-bottom: 0 !important;
     301 | }
     302 | 
     303 | .gitment-editor-body textarea {
     304 |   display: block;
     305 |   width: 100%;
     306 |   min-height: 150px;
     307 |   max-height: 500px;
     308 |   padding: 16px;
     309 |   resize: vertical;
     310 | 
     311 |   max-width: 100%;
     312 |   margin: 0;
     313 |   font-size: 14px;
     314 |   line-height: 1.6;
     315 | 
     316 |   background-color: #fff;
     317 | 
     318 |   color: #333;
     319 |   vertical-align: middle;
     320 |   border: none;
     321 |   border-radius: 0;
     322 |   outline: none;
     323 |   box-shadow: none;
     324 | 
     325 |   overflow: visible;
     326 | }
     327 | 
     328 | .gitment-editor-body textarea:focus {
     329 |   background-color: #fff;
     330 | }
     331 | 
     332 | .gitment-editor-preview {
     333 |   min-height: 150px;
     334 | 
     335 |   padding: 16px;
     336 |   background-color: transparent;
     337 | 
     338 |   width: 100%;
     339 |   font-size: 14px;
     340 | 
     341 |   line-height: 1.5;
     342 |   word-wrap: break-word;
     343 | }
     344 | 
     345 | .gitment-editor-footer {
     346 |   padding: 0;
     347 |   margin-top: 10px;
     348 | }
     349 | 
     350 | .gitment-editor-footer::after {
     351 |   display: table;
     352 |   clear: both;
     353 |   content: "";
     354 | }
     355 | 
     356 | a.gitment-editor-footer-tip {
     357 |   display: inline-block;
     358 |   padding-top: 10px;
     359 |   font-size: 12px;
     360 |   color: #666;
     361 | }
     362 | 
     363 | a.gitment-editor-footer-tip:hover {
     364 |   color: #2196F3;
     365 |   text-decoration: none;
     366 | }
     367 | 
     368 | .gitment-comments-pagination {
     369 |   list-style: none;
     370 |   text-align: right;
     371 |   border-radius: 0;
     372 |   margin: -19px 0 19px 0;
     373 | }
     374 | 
     375 | .gitment-comments-page-item {
     376 |   display: inline-block;
     377 |   cursor: pointer;
     378 |   border: 1px solid #CFD8DC;
     379 |   margin-left: -1px;
     380 |   padding: .25rem .5rem;
     381 | }
     382 | 
     383 | .gitment-comments-page-item:hover {
     384 |   background-color: #f5f5f5;
     385 | }
     386 | 
     387 | .gitment-comments-page-item.gitment-selected {
     388 |   background-color: #f5f5f5;
     389 | }
     390 | 
     391 | .gitment-editor-submit,
     392 | .gitment-comments-init-btn {
     393 |   color: #fff;
     394 |   background-color: #00BCD4;
     395 | 
     396 |   position: relative;
     397 |   display: inline-block;
     398 |   padding: 7px 13px;
     399 |   font-size: 14px;
     400 |   font-weight: 600;
     401 |   line-height: 20px;
     402 |   white-space: nowrap;
     403 |   vertical-align: middle;
     404 |   cursor: pointer;
     405 |   -webkit-user-select: none;
     406 |   -moz-user-select: none;
     407 |   -ms-user-select: none;
     408 |   user-select: none;
     409 |   background-size: 110% 110%;
     410 |   border: none;
     411 |   -webkit-appearance: none;
     412 |   -moz-appearance: none;
     413 |   appearance: none;
     414 | }
     415 | 
     416 | .gitment-editor-submit:hover,
     417 | .gitment-comments-init-btn:hover {
     418 |   background-color: #00ACC1;
     419 | }
     420 | 
     421 | .gitment-comments-init-btn:disabled,
     422 | .gitment-editor-submit:disabled {
     423 |   color: rgba(255,255,255,0.75);
     424 |   background-color: #4DD0E1;
     425 |   box-shadow: none;
     426 | }
     427 | 
     428 | .gitment-editor-submit {
     429 |   float: right;
     430 | }
     431 | 
     432 | .gitment-footer-container {
     433 |   margin-top: 30px;
     434 |   margin-bottom: 20px;
     435 |   text-align: right;
     436 |   font-size: 12px;
     437 | }
     438 | 
     439 | /*
     440 |  * Markdown CSS
     441 |  * Copied from https://github.com/sindresorhus/github-markdown-css
     442 |  */
     443 | .gitment-markdown {
     444 |   -ms-text-size-adjust: 100%;
     445 |   -webkit-text-size-adjust: 100%;
     446 |   line-height: 1.5;
     447 |   color: #333;
     448 |   font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
     449 |   font-size: 16px;
     450 |   line-height: 1.5;
     451 |   word-wrap: break-word;
     452 | }
     453 | 
     454 | .gitment-markdown .pl-c {
     455 |   color: #969896;
     456 | }
     457 | 
     458 | .gitment-markdown .pl-c1,
     459 | .gitment-markdown .pl-s .pl-v {
     460 |   color: #0086b3;
     461 | }
     462 | 
     463 | .gitment-markdown .pl-e,
     464 | .gitment-markdown .pl-en {
     465 |   color: #795da3;
     466 | }
     467 | 
     468 | .gitment-markdown .pl-smi,
     469 | .gitment-markdown .pl-s .pl-s1 {
     470 |   color: #333;
     471 | }
     472 | 
     473 | .gitment-markdown .pl-ent {
     474 |   color: #63a35c;
     475 | }
     476 | 
     477 | .gitment-markdown .pl-k {
     478 |   color: #a71d5d;
     479 | }
     480 | 
     481 | .gitment-markdown .pl-s,
     482 | .gitment-markdown .pl-pds,
     483 | .gitment-markdown .pl-s .pl-pse .pl-s1,
     484 | .gitment-markdown .pl-sr,
     485 | .gitment-markdown .pl-sr .pl-cce,
     486 | .gitment-markdown .pl-sr .pl-sre,
     487 | .gitment-markdown .pl-sr .pl-sra {
     488 |   color: #183691;
     489 | }
     490 | 
     491 | .gitment-markdown .pl-v,
     492 | .gitment-markdown .pl-smw {
     493 |   color: #ed6a43;
     494 | }
     495 | 
     496 | .gitment-markdown .pl-bu {
     497 |   color: #b52a1d;
     498 | }
     499 | 
     500 | .gitment-markdown .pl-ii {
     501 |   color: #f8f8f8;
     502 |   background-color: #b52a1d;
     503 | }
     504 | 
     505 | .gitment-markdown .pl-c2 {
     506 |   color: #f8f8f8;
     507 |   background-color: #b52a1d;
     508 | }
     509 | 
     510 | .gitment-markdown .pl-c2::before {
     511 |   content: "^M";
     512 | }
     513 | 
     514 | .gitment-markdown .pl-sr .pl-cce {
     515 |   font-weight: bold;
     516 |   color: #63a35c;
     517 | }
     518 | 
     519 | .gitment-markdown .pl-ml {
     520 |   color: #693a17;
     521 | }
     522 | 
     523 | .gitment-markdown .pl-mh,
     524 | .gitment-markdown .pl-mh .pl-en,
     525 | .gitment-markdown .pl-ms {
     526 |   font-weight: bold;
     527 |   color: #1d3e81;
     528 | }
     529 | 
     530 | .gitment-markdown .pl-mq {
     531 |   color: #008080;
     532 | }
     533 | 
     534 | .gitment-markdown .pl-mi {
     535 |   font-style: italic;
     536 |   color: #333;
     537 | }
     538 | 
     539 | .gitment-markdown .pl-mb {
     540 |   font-weight: bold;
     541 |   color: #333;
     542 | }
     543 | 
     544 | .gitment-markdown .pl-md {
     545 |   color: #bd2c00;
     546 |   background-color: #ffecec;
     547 | }
     548 | 
     549 | .gitment-markdown .pl-mi1 {
     550 |   color: #55a532;
     551 |   background-color: #eaffea;
     552 | }
     553 | 
     554 | .gitment-markdown .pl-mc {
     555 |   color: #ef9700;
     556 |   background-color: #ffe3b4;
     557 | }
     558 | 
     559 | .gitment-markdown .pl-mi2 {
     560 |   color: #d8d8d8;
     561 |   background-color: #808080;
     562 | }
     563 | 
     564 | .gitment-markdown .pl-mdr {
     565 |   font-weight: bold;
     566 |   color: #795da3;
     567 | }
     568 | 
     569 | .gitment-markdown .pl-mo {
     570 |   color: #1d3e81;
     571 | }
     572 | 
     573 | .gitment-markdown .pl-ba {
     574 |   color: #595e62;
     575 | }
     576 | 
     577 | .gitment-markdown .pl-sg {
     578 |   color: #c0c0c0;
     579 | }
     580 | 
     581 | .gitment-markdown .pl-corl {
     582 |   text-decoration: underline;
     583 |   color: #183691;
     584 | }
     585 | 
     586 | .gitment-markdown .octicon {
     587 |   display: inline-block;
     588 |   vertical-align: text-top;
     589 |   fill: currentColor;
     590 | }
     591 | 
     592 | .gitment-markdown a {
     593 |   background-color: transparent;
     594 |   -webkit-text-decoration-skip: objects;
     595 | }
     596 | 
     597 | .gitment-markdown a:active,
     598 | .gitment-markdown a:hover {
     599 |   outline-width: 0;
     600 | }
     601 | 
     602 | .gitment-markdown strong {
     603 |   font-weight: inherit;
     604 | }
     605 | 
     606 | .gitment-markdown strong {
     607 |   font-weight: bolder;
     608 | }
     609 | 
     610 | .gitment-markdown h1 {
     611 |   font-size: 2em;
     612 |   margin: 0.67em 0;
     613 | }
     614 | 
     615 | .gitment-markdown img {
     616 |   border-style: none;
     617 | }
     618 | 
     619 | .gitment-markdown svg:not(:root) {
     620 |   overflow: hidden;
     621 | }
     622 | 
     623 | .gitment-markdown code,
     624 | .gitment-markdown kbd,
     625 | .gitment-markdown pre {
     626 |   font-family: monospace, monospace;
     627 |   font-size: 1em;
     628 | }
     629 | 
     630 | .gitment-markdown hr {
     631 |   box-sizing: content-box;
     632 |   height: 0;
     633 |   overflow: visible;
     634 | }
     635 | 
     636 | .gitment-markdown input {
     637 |   font: inherit;
     638 |   margin: 0;
     639 | }
     640 | 
     641 | .gitment-markdown input {
     642 |   overflow: visible;
     643 | }
     644 | 
     645 | .gitment-markdown [type="checkbox"] {
     646 |   box-sizing: border-box;
     647 |   padding: 0;
     648 | }
     649 | 
     650 | .gitment-markdown * {
     651 |   box-sizing: border-box;
     652 | }
     653 | 
     654 | .gitment-markdown input {
     655 |   font-family: inherit;
     656 |   font-size: inherit;
     657 |   line-height: inherit;
     658 | }
     659 | 
     660 | .gitment-markdown a {
     661 |   color: #0366d6;
     662 |   text-decoration: none;
     663 | }
     664 | 
     665 | .gitment-markdown a:hover {
     666 |   text-decoration: underline;
     667 | }
     668 | 
     669 | .gitment-markdown strong {
     670 |   font-weight: 600;
     671 | }
     672 | 
     673 | .gitment-markdown hr {
     674 |   height: 0;
     675 |   margin: 15px 0;
     676 |   overflow: hidden;
     677 |   background: transparent;
     678 |   border: 0;
     679 |   border-bottom: 1px solid #dfe2e5;
     680 | }
     681 | 
     682 | .gitment-markdown hr::before {
     683 |   display: table;
     684 |   content: "";
     685 | }
     686 | 
     687 | .gitment-markdown hr::after {
     688 |   display: table;
     689 |   clear: both;
     690 |   content: "";
     691 | }
     692 | 
     693 | .gitment-markdown table {
     694 |   border-spacing: 0;
     695 |   border-collapse: collapse;
     696 | }
     697 | 
     698 | .gitment-markdown td,
     699 | .gitment-markdown th {
     700 |   padding: 0;
     701 | }
     702 | 
     703 | .gitment-markdown h1,
     704 | .gitment-markdown h2,
     705 | .gitment-markdown h3,
     706 | .gitment-markdown h4,
     707 | .gitment-markdown h5,
     708 | .gitment-markdown h6 {
     709 |   margin-top: 0;
     710 |   margin-bottom: 0;
     711 | }
     712 | 
     713 | .gitment-markdown h1 {
     714 |   font-size: 32px;
     715 |   font-weight: 600;
     716 | }
     717 | 
     718 | .gitment-markdown h2 {
     719 |   font-size: 24px;
     720 |   font-weight: 600;
     721 | }
     722 | 
     723 | .gitment-markdown h3 {
     724 |   font-size: 20px;
     725 |   font-weight: 600;
     726 | }
     727 | 
     728 | .gitment-markdown h4 {
     729 |   font-size: 16px;
     730 |   font-weight: 600;
     731 | }
     732 | 
     733 | .gitment-markdown h5 {
     734 |   font-size: 14px;
     735 |   font-weight: 600;
     736 | }
     737 | 
     738 | .gitment-markdown h6 {
     739 |   font-size: 12px;
     740 |   font-weight: 600;
     741 | }
     742 | 
     743 | .gitment-markdown p {
     744 |   margin-top: 0;
     745 |   margin-bottom: 10px;
     746 | }
     747 | 
     748 | .gitment-markdown blockquote {
     749 |   margin: 0;
     750 | }
     751 | 
     752 | .gitment-markdown ul,
     753 | .gitment-markdown ol {
     754 |   padding-left: 0;
     755 |   margin-top: 0;
     756 |   margin-bottom: 0;
     757 | }
     758 | 
     759 | .gitment-markdown ol ol,
     760 | .gitment-markdown ul ol {
     761 |   list-style-type: lower-roman;
     762 | }
     763 | 
     764 | .gitment-markdown ul ul ol,
     765 | .gitment-markdown ul ol ol,
     766 | .gitment-markdown ol ul ol,
     767 | .gitment-markdown ol ol ol {
     768 |   list-style-type: lower-alpha;
     769 | }
     770 | 
     771 | .gitment-markdown dd {
     772 |   margin-left: 0;
     773 | }
     774 | 
     775 | .gitment-markdown code {
     776 |   font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
     777 |   font-size: 12px;
     778 | }
     779 | 
     780 | .gitment-markdown pre {
     781 |   margin-top: 0;
     782 |   margin-bottom: 0;
     783 |   font: 12px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
     784 | }
     785 | 
     786 | .gitment-markdown .octicon {
     787 |   vertical-align: text-bottom;
     788 | }
     789 | 
     790 | .gitment-markdown .pl-0 {
     791 |   padding-left: 0 !important;
     792 | }
     793 | 
     794 | .gitment-markdown .pl-1 {
     795 |   padding-left: 4px !important;
     796 | }
     797 | 
     798 | .gitment-markdown .pl-2 {
     799 |   padding-left: 8px !important;
     800 | }
     801 | 
     802 | .gitment-markdown .pl-3 {
     803 |   padding-left: 16px !important;
     804 | }
     805 | 
     806 | .gitment-markdown .pl-4 {
     807 |   padding-left: 24px !important;
     808 | }
     809 | 
     810 | .gitment-markdown .pl-5 {
     811 |   padding-left: 32px !important;
     812 | }
     813 | 
     814 | .gitment-markdown .pl-6 {
     815 |   padding-left: 40px !important;
     816 | }
     817 | 
     818 | .gitment-markdown::before {
     819 |   display: table;
     820 |   content: "";
     821 | }
     822 | 
     823 | .gitment-markdown::after {
     824 |   display: table;
     825 |   clear: both;
     826 |   content: "";
     827 | }
     828 | 
     829 | .gitment-markdown>*:first-child {
     830 |   margin-top: 0 !important;
     831 | }
     832 | 
     833 | .gitment-markdown>*:last-child {
     834 |   margin-bottom: 0 !important;
     835 | }
     836 | 
     837 | .gitment-markdown a:not([href]) {
     838 |   color: inherit;
     839 |   text-decoration: none;
     840 | }
     841 | 
     842 | .gitment-markdown .anchor {
     843 |   float: left;
     844 |   padding-right: 4px;
     845 |   margin-left: -20px;
     846 |   line-height: 1;
     847 | }
     848 | 
     849 | .gitment-markdown .anchor:focus {
     850 |   outline: none;
     851 | }
     852 | 
     853 | .gitment-markdown p,
     854 | .gitment-markdown blockquote,
     855 | .gitment-markdown ul,
     856 | .gitment-markdown ol,
     857 | .gitment-markdown dl,
     858 | .gitment-markdown table,
     859 | .gitment-markdown pre {
     860 |   margin-top: 0;
     861 |   margin-bottom: 16px;
     862 | }
     863 | 
     864 | .gitment-markdown hr {
     865 |   height: 0.25em;
     866 |   padding: 0;
     867 |   margin: 24px 0;
     868 |   background-color: #e1e4e8;
     869 |   border: 0;
     870 | }
     871 | 
     872 | .gitment-markdown blockquote {
     873 |   padding: 0 1em;
     874 |   color: #6a737d;
     875 |   border-left: 0.25em solid #dfe2e5;
     876 | }
     877 | 
     878 | .gitment-markdown blockquote>:first-child {
     879 |   margin-top: 0;
     880 | }
     881 | 
     882 | .gitment-markdown blockquote>:last-child {
     883 |   margin-bottom: 0;
     884 | }
     885 | 
     886 | .gitment-markdown kbd {
     887 |   display: inline-block;
     888 |   padding: 3px 5px;
     889 |   font-size: 11px;
     890 |   line-height: 10px;
     891 |   color: #444d56;
     892 |   vertical-align: middle;
     893 |   background-color: #fafbfc;
     894 |   border: solid 1px #c6cbd1;
     895 |   border-bottom-color: #959da5;
     896 |   border-radius: 0;
     897 |   box-shadow: inset 0 -1px 0 #959da5;
     898 | }
     899 | 
     900 | .gitment-markdown h1,
     901 | .gitment-markdown h2,
     902 | .gitment-markdown h3,
     903 | .gitment-markdown h4,
     904 | .gitment-markdown h5,
     905 | .gitment-markdown h6 {
     906 |   margin-top: 24px;
     907 |   margin-bottom: 16px;
     908 |   font-weight: 600;
     909 |   line-height: 1.25;
     910 | }
     911 | 
     912 | .gitment-markdown h1 .octicon-link,
     913 | .gitment-markdown h2 .octicon-link,
     914 | .gitment-markdown h3 .octicon-link,
     915 | .gitment-markdown h4 .octicon-link,
     916 | .gitment-markdown h5 .octicon-link,
     917 | .gitment-markdown h6 .octicon-link {
     918 |   color: #1b1f23;
     919 |   vertical-align: middle;
     920 |   visibility: hidden;
     921 | }
     922 | 
     923 | .gitment-markdown h1:hover .anchor,
     924 | .gitment-markdown h2:hover .anchor,
     925 | .gitment-markdown h3:hover .anchor,
     926 | .gitment-markdown h4:hover .anchor,
     927 | .gitment-markdown h5:hover .anchor,
     928 | .gitment-markdown h6:hover .anchor {
     929 |   text-decoration: none;
     930 | }
     931 | 
     932 | .gitment-markdown h1:hover .anchor .octicon-link,
     933 | .gitment-markdown h2:hover .anchor .octicon-link,
     934 | .gitment-markdown h3:hover .anchor .octicon-link,
     935 | .gitment-markdown h4:hover .anchor .octicon-link,
     936 | .gitment-markdown h5:hover .anchor .octicon-link,
     937 | .gitment-markdown h6:hover .anchor .octicon-link {
     938 |   visibility: visible;
     939 | }
     940 | 
     941 | .gitment-markdown h1 {
     942 |   padding-bottom: 0.3em;
     943 |   font-size: 2em;
     944 |   border-bottom: 1px solid #eaecef;
     945 | }
     946 | 
     947 | .gitment-markdown h2 {
     948 |   padding-bottom: 0.3em;
     949 |   font-size: 1.5em;
     950 |   border-bottom: 1px solid #eaecef;
     951 | }
     952 | 
     953 | .gitment-markdown h3 {
     954 |   font-size: 1.25em;
     955 | }
     956 | 
     957 | .gitment-markdown h4 {
     958 |   font-size: 1em;
     959 | }
     960 | 
     961 | .gitment-markdown h5 {
     962 |   font-size: 0.875em;
     963 | }
     964 | 
     965 | .gitment-markdown h6 {
     966 |   font-size: 0.85em;
     967 |   color: #6a737d;
     968 | }
     969 | 
     970 | .gitment-markdown ul,
     971 | .gitment-markdown ol {
     972 |   padding-left: 2em;
     973 | }
     974 | 
     975 | .gitment-markdown ul ul,
     976 | .gitment-markdown ul ol,
     977 | .gitment-markdown ol ol,
     978 | .gitment-markdown ol ul {
     979 |   margin-top: 0;
     980 |   margin-bottom: 0;
     981 | }
     982 | 
     983 | .gitment-markdown li>p {
     984 |   margin-top: 16px;
     985 | }
     986 | 
     987 | .gitment-markdown li+li {
     988 |   margin-top: 0.25em;
     989 | }
     990 | 
     991 | .gitment-markdown dl {
     992 |   padding: 0;
     993 | }
     994 | 
     995 | .gitment-markdown dl dt {
     996 |   padding: 0;
     997 |   margin-top: 16px;
     998 |   font-size: 1em;
     999 |   font-style: italic;
    1000 |   font-weight: 600;
    1001 | }
    1002 | 
    1003 | .gitment-markdown dl dd {
    1004 |   padding: 0 16px;
    1005 |   margin-bottom: 16px;
    1006 | }
    1007 | 
    1008 | .gitment-markdown table {
    1009 |   display: block;
    1010 |   width: 100%;
    1011 |   overflow: auto;
    1012 | }
    1013 | 
    1014 | .gitment-markdown table th {
    1015 |   font-weight: 600;
    1016 | }
    1017 | 
    1018 | .gitment-markdown table th,
    1019 | .gitment-markdown table td {
    1020 |   padding: 6px 13px;
    1021 |   border: 1px solid #dfe2e5;
    1022 | }
    1023 | 
    1024 | .gitment-markdown table tr {
    1025 |   background-color: #fff;
    1026 |   border-top: 1px solid #c6cbd1;
    1027 | }
    1028 | 
    1029 | .gitment-markdown table tr:nth-child(2n) {
    1030 |   background-color: #f5f5f5;
    1031 | }
    1032 | 
    1033 | .gitment-markdown img {
    1034 |   max-width: 100%;
    1035 |   box-sizing: content-box;
    1036 |   background-color: #fff;
    1037 | }
    1038 | 
    1039 | .gitment-markdown code {
    1040 |   padding: 0;
    1041 |   padding-top: 0.2em;
    1042 |   padding-bottom: 0.2em;
    1043 |   margin: 0;
    1044 |   font-size: 85%;
    1045 |   background-color: rgba(27,31,35,0.05);
    1046 |   border-radius: 0;
    1047 | }
    1048 | 
    1049 | .gitment-markdown code::before,
    1050 | .gitment-markdown code::after {
    1051 |   letter-spacing: -0.2em;
    1052 |   content: "\00a0";
    1053 | }
    1054 | 
    1055 | .gitment-markdown pre {
    1056 |   word-wrap: normal;
    1057 | }
    1058 | 
    1059 | .gitment-markdown pre>code {
    1060 |   padding: 0;
    1061 |   margin: 0;
    1062 |   font-size: 100%;
    1063 |   word-break: normal;
    1064 |   white-space: pre;
    1065 |   background: transparent;
    1066 |   border: 0;
    1067 | }
    1068 | 
    1069 | .gitment-markdown .highlight {
    1070 |   margin-bottom: 16px;
    1071 | }
    1072 | 
    1073 | .gitment-markdown .highlight pre {
    1074 |   margin-bottom: 0;
    1075 |   word-break: normal;
    1076 | }
    1077 | 
    1078 | .gitment-markdown .highlight pre,
    1079 | .gitment-markdown pre {
    1080 |   padding: 16px;
    1081 |   overflow: auto;
    1082 |   font-size: 85%;
    1083 |   line-height: 1.45;
    1084 |   background-color: #f5f5f5;
    1085 |   border-radius: 0;
    1086 | }
    1087 | 
    1088 | .gitment-markdown pre code {
    1089 |   display: inline;
    1090 |   max-width: auto;
    1091 |   padding: 0;
    1092 |   margin: 0;
    1093 |   overflow: visible;
    1094 |   line-height: inherit;
    1095 |   word-wrap: normal;
    1096 |   background-color: transparent;
    1097 |   border: 0;
    1098 | }
    1099 | 
    1100 | .gitment-markdown pre code::before,
    1101 | .gitment-markdown pre code::after {
    1102 |   content: normal;
    1103 | }
    1104 | 
    1105 | .gitment-markdown .full-commit .btn-outline:not(:disabled):hover {
    1106 |   color: #005cc5;
    1107 |   border-color: #005cc5;
    1108 | }
    1109 | 
    1110 | .gitment-markdown kbd {
    1111 |   display: inline-block;
    1112 |   padding: 3px 5px;
    1113 |   font: 11px "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
    1114 |   line-height: 10px;
    1115 |   color: #444d56;
    1116 |   vertical-align: middle;
    1117 |   background-color: #fcfcfc;
    1118 |   border: solid 1px #c6cbd1;
    1119 |   border-bottom-color: #959da5;
    1120 |   border-radius: 0;
    1121 |   box-shadow: inset 0 -1px 0 #959da5;
    1122 | }
    1123 | 
    1124 | .gitment-markdown :checked+.radio-label {
    1125 |   position: relative;
    1126 |   z-index: 1;
    1127 |   border-color: #0366d6;
    1128 | }
    1129 | 
    1130 | .gitment-markdown .task-list-item {
    1131 |   list-style-type: none;
    1132 | }
    1133 | 
    1134 | .gitment-markdown .task-list-item+.task-list-item {
    1135 |   margin-top: 3px;
    1136 | }
    1137 | 
    1138 | .gitment-markdown .task-list-item input {
    1139 |   margin: 0 0.2em 0.25em -1.6em;
    1140 |   vertical-align: middle;
    1141 | }
    1142 | 
    1143 | .gitment-markdown hr {
    1144 |   border-bottom-color: #eee;
    1145 | }
    1146 | 
    
    
    --------------------------------------------------------------------------------
    /js/gitblog.js:
    --------------------------------------------------------------------------------
      1 | var gitblog = function(config) {
      2 |     var self = this;
      3 | 
      4 |     self.getUrlParam = function(name) {
      5 |         var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
      6 |         var r = window.location.search.substr(1).match(reg);
      7 |         if (r != null) return decodeURI(r[2]);
      8 |         return null;
      9 |     }
     10 | 
     11 |     self.options = {
     12 |         id: null,
     13 |         label: null,
     14 |         q: null,
     15 |         page: 1,
     16 |         token: null,
     17 |         code: null,
     18 |         redirect_url: null,
     19 |     }
     20 | 
     21 |     self.set = function() {
     22 |         if (self.getUrlParam('id') != undefined) {
     23 |             self.options.id = parseInt(self.getUrlParam('id'));
     24 |         }
     25 |         if (self.getUrlParam('label') != undefined) {
     26 |             self.options.label = self.getUrlParam('label');
     27 |         }
     28 |         if (self.getUrlParam('q') != undefined) {
     29 |             self.options.q = self.getUrlParam('q');
     30 |         }
     31 |         if (self.getUrlParam('page') != undefined) {
     32 |             self.options.page = parseInt(self.getUrlParam('page'));
     33 |         }
     34 |         if (self.getUrlParam('access_token') != undefined) {
     35 |             self.options.token = self.getUrlParam('access_token');
     36 |         }
     37 |         if (self.getUrlParam('code') != undefined) {
     38 |             self.options.code = self.getUrlParam('code');
     39 |         }
     40 |         if (self.getUrlParam('state') != undefined) {
     41 |             self.options.redirect_url = self.getUrlParam('state');
     42 |         }
     43 | 
     44 |         if (self.options.code != null && self.options.redirect_url != null) {
     45 |             window.location.href = config.server_link + "?code=" + self.options.code + "&redirect_url=" + self.options.redirect_url + "&client_id=" + config.client_id + "&client_secret=" + config.client_secret;
     46 |         }
     47 |     }
     48 | 
     49 |     self.set();
     50 | 
     51 |     self.utc2localTime = function(time) {
     52 |         var time_string_utc_epoch = Date.parse(time);
     53 |         var unixTimestamp = new Date(time_string_utc_epoch);
     54 |         var year = unixTimestamp.getFullYear();
     55 |         var month = unixTimestamp.getMonth() + 1;
     56 |         var date = unixTimestamp.getDate();
     57 |         var hour = unixTimestamp.getHours();
     58 |         var minute = unixTimestamp.getMinutes();
     59 |         var second = unixTimestamp.getSeconds();
     60 |         hour = (hour<10)?'0'+hour:hour;
     61 |         minute = (minute<10)?'0'+minute:minute;
     62 |         second = (second<10)?'0'+second:second;
     63 |         return year+'年'+month+'月'+date+'日'+' '+hour+':'+minute+':'+second;
     64 |     }
     65 | 
     66 |     String.prototype.replaceAll = function(a, b) {
     67 |         return this.replace(new RegExp(a, 'gm'), b);
     68 |     }
     69 | 
     70 |     var Info = function() {
     71 |         this.title = config.title;
     72 |         this.instruction = config.instruction;
     73 |     }
     74 | 
     75 |     Info.prototype.init = function() {
     76 |         $('#title').text(this.title);
     77 |         $('#instruction').text(this.instruction);
     78 |         document.getElementsByTagName("title")[0].innerText = this.title;
     79 |     }
     80 | 
     81 |     var Menu = function() {
     82 |         this.labels = [];
     83 |     }
     84 | 
     85 |     Menu.prototype = {
     86 |         searchOnblur: function() {
     87 |             if ($('.search-input').val() == "") {
     88 |                 $(".search-input").css("width", '42px');
     89 |                 $(".search-input").css("z-index", -1);
     90 |             }
     91 |         },
     92 |         show: function() {
     93 |             var menu = this;
     94 |             for(var name in config.menu) {
     95 |                 document.getElementById("menu").innerHTML += '
  • ' + name + '
  • '; 96 | } 97 | if (Object.keys(config.friends).length != 0) { 98 | var menu_friend = document.getElementById("friends"); 99 | menu_friend.innerHTML = '
  • 友链:
  • '; 100 | for (var name in config.friends) { 101 | menu_friend.innerHTML += '
  • ' + name + '
  • '; 102 | } 103 | } 104 | $(".search-input").on("blur", 105 | function() { 106 | menu.searchOnblur(); 107 | }); 108 | } 109 | } 110 | 111 | var Icon = function(options, name, left) { 112 | this.icon_src = options.icon_src; 113 | this.href = options.href; 114 | this.hidden_img = options.hidden_img; 115 | this.width = options.width; 116 | this.name = name; 117 | this.position = left; 118 | } 119 | 120 | Icon.prototype = { 121 | init: function() { 122 | var icon = this; 123 | if(icon.href != undefined && icon.href != null) { 124 | document.getElementById("div_"+icon.name).innerHTML += ''; 125 | } else { 126 | document.getElementById("div_"+icon.name).innerHTML += ''; 127 | } 128 | if (icon.hidden_img != undefined && icon.hidden_img != null) { 129 | document.getElementById("div_"+icon.name).innerHTML += ''; 130 | $('#icon_' + icon.name).mouseover(function() { 131 | icon.changeIcon(icon.name, 'show'); 132 | }); 133 | $('#icon_' + icon.name).mouseout(function() { 134 | icon.changeIcon(icon.name, 'hidden'); 135 | }); 136 | } 137 | }, 138 | changeIcon: function(id, action) { 139 | if (action == 'show') { 140 | $('#' + id).css('z-index', '99'); 141 | $('#' + id).css("opacity", "1"); 142 | $('#' + id).css("transform", "translateY(0)"); 143 | } else if (action == 'hidden') { 144 | $('#' + id).css('z-index', '-1'); 145 | $('#' + id).css("opacity", "0"); 146 | $('#' + id).css("transform", "translateY(-20px)"); 147 | } 148 | } 149 | } 150 | 151 | var Footer = function() { 152 | this.page = new Pages(); 153 | this.icons = []; 154 | this.icon_num = 0; 155 | this.content = 'Powered by gitblog'; 156 | } 157 | 158 | Footer.prototype = { 159 | showIcon: function() { 160 | var footer = this; 161 | for (var i in config.icons) { 162 | if (config.icons[i].icon_src != undefined && config.icons[i].icon_src != null) { 163 | document.getElementById('icon').innerHTML += '
    '; 164 | } 165 | } 166 | for (var i in config.icons) { 167 | if (config.icons[i].icon_src != undefined && config.icons[i].icon_src != null) { 168 | var left = Object.keys(config.icons).length * 35 - 70 * footer.icon_num + config.icons[i].width / 2 - 35; 169 | var icon = new Icon(config.icons[i], i, left); 170 | icon.init(); 171 | footer.icons.push(icon); 172 | footer.icon_num++; 173 | } 174 | } 175 | }, 176 | show: function() { 177 | document.getElementById('footer').innerHTML += this.content; 178 | this.showIcon(); 179 | } 180 | } 181 | 182 | var Pages = function() { 183 | this.page = 1; 184 | this.pages = 1; 185 | this.itemNum = 0; 186 | this.pageLimit = 7; 187 | } 188 | 189 | Pages.prototype = { 190 | getNum: function(request_url) { 191 | var page = this; 192 | if (self.options.page != null && self.options.page != undefined) { 193 | page.page = self.options.page; 194 | } 195 | $.ajax({ 196 | type: 'get', 197 | url: request_url, 198 | success: function(data) { 199 | if (self.options.label != null && self.options.label != undefined) { 200 | page.itemNum = data.length; 201 | } else if(self.options.q != null && self.options.q != undefined) { 202 | page.itemNum = data.total_count; 203 | } else if (self.options.id != null && self.options.id != undefined) { 204 | page.itemNum = data.length; 205 | document.getElementById('comments-num').innerHTML = page.itemNum; 206 | } else { 207 | page.itemNum = data.open_issues_count; 208 | } 209 | if (page.itemNum > 10) { 210 | page.pages = Math.ceil(page.itemNum / 10); 211 | page.show(); 212 | } 213 | } 214 | }); 215 | }, 216 | show: function() { 217 | var page = this; 218 | $('#pages').css('display', 'inline-block'); 219 | document.getElementById('pages').innerHTML = '
  • «
  • '; 220 | if (page.pages <= page.pageLimit) { 221 | for (var i = 1; i <= page.pages; i++) { 222 | document.getElementById('pages').innerHTML += '
  • ' + i + '
  • '; 223 | } 224 | } else { 225 | if (page.page >= 5) { 226 | document.getElementById('pages').innerHTML += '
  • 1
  • '; 227 | document.getElementById('pages').innerHTML += '
  • ...
  • '; 228 | document.getElementById('pages').innerHTML += '
  • ' + (page.page - 1) + '
  • '; 229 | document.getElementById('pages').innerHTML += '
  • ' + page.page + '
  • '; 230 | } else { 231 | for (var i = 1; i <= page.page; i++) { 232 | document.getElementById('pages').innerHTML += '
  • ' + i + '
  • '; 233 | } 234 | } 235 | if (page.page <= page.pages - 4) { 236 | document.getElementById('pages').innerHTML += '
  • ' + (page.page + 1) + '
  • '; 237 | document.getElementById('pages').innerHTML += '
  • ...
  • '; 238 | document.getElementById('pages').innerHTML += '
  • ' + page.pages + '
  • '; 239 | } else { 240 | for (var i = page.page + 1; i <= page.pages; i++) { 241 | document.getElementById('pages').innerHTML += '
  • ' + i + '
  • '; 242 | } 243 | } 244 | } 245 | document.getElementById('pages').innerHTML += '
  • '; 246 | for (var i = 1; i <= page.pages; i++) { 247 | if (self.options.label != undefined) { 248 | $('#page' + i).click(function() { 249 | window.location.href = "?label=" + self.options.label + "&page=" + this.innerHTML; 250 | }); 251 | } else if (self.options.id != undefined) { 252 | $('#page' + i).click(function() { 253 | window.location.href = "?id=" + self.options.id + "&page=" + this.innerHTML; 254 | }); 255 | } else if(self.options.q != undefined) { 256 | $('#page' + i).click(function() { 257 | window.location.href = "?q=" + self.options.q + "&page=" + this.innerHTML; 258 | }); 259 | } else { 260 | $('#page' + i).click(function() { 261 | window.location.href = "?page=" + this.innerHTML; 262 | }); 263 | } 264 | if (i == page.page) { 265 | $('#page' + i).addClass('active'); 266 | } else { 267 | $('#page' + i).removeClass('active'); 268 | } 269 | } 270 | if (page.page == 1) { 271 | $('#last_page').css('pointer-events', 'none'); 272 | $('#next_page').css('pointer-events', 'auto'); 273 | } else if (page.page == page.pages) { 274 | $('#last_page').css('pointer-events', 'auto'); 275 | $('#next_page').css('pointer-events', 'none'); 276 | } 277 | document.getElementById('last').onclick = function() { 278 | page.last(); 279 | } 280 | document.getElementById('next').onclick = function() { 281 | page.next(); 282 | } 283 | }, 284 | last: function() { 285 | this.page--; 286 | if (self.options.label != undefined) { 287 | window.location.href = '?label=' + self.options.label + '&page=' + this.page; 288 | } else if (self.options.id != undefined && self.options.id != null) { 289 | window.location.href = '?id=' + self.options.id + '&page=' + this.page; 290 | } else { 291 | window.location.href = '?page=' + this.page; 292 | } 293 | }, 294 | next: function() { 295 | this.page++; 296 | if (self.options.label != undefined) { 297 | window.location.href = '?label=' + self.options.label + '&page=' + this.page; 298 | } else if (self.options.id != undefined && self.options.id != null) { 299 | window.location.href = '?id=' + self.options.id + '&page=' + this.page; 300 | } else { 301 | window.location.href = '?page=' + this.page; 302 | } 303 | } 304 | } 305 | 306 | var Reaction = function() { 307 | this.num = 0; 308 | this.isLike = false; 309 | } 310 | 311 | Reaction.prototype = { 312 | like: function(type, id) { 313 | var reaction = this; 314 | if (reaction.isLike == true) return; 315 | if (window.localStorage.access_token == undefined || window.localStorage.access_token == null) { 316 | alert("请先登录!"); 317 | return; 318 | } 319 | var request_url = ''; 320 | if (type == 'issue') { 321 | request_url = 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/issues/' + id + '/reactions'; 322 | } else if (type == 'comment') { 323 | request_url = 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/issues/comments/' + id + '/reactions'; 324 | } 325 | $.ajax({ 326 | type: "post", 327 | url: request_url, 328 | headers: { 329 | Authorization: 'Basic ' + window.localStorage.authorize, 330 | Accept: 'application/vnd.github.squirrel-girl-preview+json' 331 | }, 332 | data: JSON.stringify({ 333 | "content": "heart" 334 | }), 335 | success: function() { 336 | reaction.num += 1; 337 | reaction.isLike = true; 338 | reaction.show(type, id); 339 | } 340 | }); 341 | }, 342 | getNum: function(type, id) { 343 | var reaction = this; 344 | var request_url = ''; 345 | if (type == 'issue') { 346 | request_url = 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/issues/' + id + '/reactions'; 347 | } else if (type == 'comment') { 348 | request_url = 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/issues/comments/' + id + '/reactions'; 349 | } 350 | $.ajax({ 351 | type: "get", 352 | url: request_url + '?content=heart', 353 | headers: { 354 | Accept: 'application/vnd.github.squirrel-girl-preview+json' 355 | }, 356 | success: function(data) { 357 | for (var i in data) { 358 | if (data[i].user.login == window.localStorage.name) { 359 | reaction.isLike = true; 360 | } 361 | } 362 | reaction.num = data.length; 363 | reaction.show(type, id); 364 | } 365 | }); 366 | }, 367 | show: function(type, id) { 368 | var reaction = this; 369 | if (reaction.isLike == false) { 370 | document.getElementById(id).innerHTML = ''; 371 | } else if (reaction.isLike == true) { 372 | document.getElementById(id).innerHTML = '❤️'; 373 | } 374 | document.getElementById(id).innerHTML += reaction.num; 375 | document.getElementById(id).onclick = function() { 376 | reaction.like(type, id); 377 | }; 378 | } 379 | } 380 | 381 | var commentItem = function() { 382 | this.reaction = new Reaction(); 383 | } 384 | 385 | var Comment = function() { 386 | this.login = false; 387 | this.item = []; 388 | } 389 | 390 | Comment.prototype = { 391 | send: function() { 392 | var comment = this; 393 | var input = document.getElementById('comment-input').value; 394 | $.ajax({ 395 | type: "post", 396 | url: 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/issues/' + self.options.id + '/comments', 397 | headers: { 398 | Authorization: 'Basic ' + window.localStorage.authorize, 399 | Accept: 'application/vnd.github.squirrel-girl-preview, application/vnd.github.html+json', 400 | 'Content-Type': 'application/json' 401 | }, 402 | data: JSON.stringify({ 403 | "body": input 404 | }), 405 | dataType: "json", 406 | success: function(data) { 407 | if (data.id != undefined) { 408 | document.getElementById('comment-input').value = ""; 409 | comment.addComment(data); 410 | document.getElementById('comments-num').innerHTML++; 411 | } 412 | } 413 | }); 414 | }, 415 | init: function() { 416 | var comment = this; 417 | comment.checkIsLogin(); 418 | $.ajax({ 419 | type: 'get', 420 | headers: { 421 | Accept: 'application/vnd.github.squirrel-girl-preview, application/vnd.github.html+json, application/x-www-form-urlencoded', 422 | }, 423 | url: 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/issues/' + self.options.id + '/comments?page=' + self.options.page + '&per_page=10', 424 | success: function(data) { 425 | document.getElementById('comment-list').innerHTML = ""; 426 | for (var i in data) { 427 | comment.addComment(data[i]); 428 | } 429 | } 430 | }); 431 | 432 | var login = document.getElementById('login'); 433 | if (comment.login == false) { 434 | login.innerHTML = '登入 with GitHub'; 435 | } else { 436 | login.innerHTML = '登出'; 437 | } 438 | 439 | document.getElementById('log').onclick = function() { 440 | if (comment.login == false) { 441 | comment.log(); 442 | } else { 443 | comment.logout(); 444 | } 445 | } 446 | 447 | var editor_content = document.getElementById('write-field'); 448 | if (comment.login == false) { 449 | editor_content.innerHTML = ''; 450 | $('.gitment-editor-submit').attr("disabled", true); 451 | } else { 452 | editor_content.innerHTML = ''; 453 | $('.gitment-editor-submit').attr("disabled", false); 454 | } 455 | 456 | $('#editComment').click(function() { 457 | comment.edit(); 458 | }); 459 | $('#preview').click(function() { 460 | comment.preview(); 461 | }); 462 | $('.gitment-editor-submit').click(function() { 463 | comment.send(); 464 | }); 465 | }, 466 | addComment: function(data) { 467 | var comment = new commentItem(); 468 | data.created_at = self.utc2localTime(data.created_at); 469 | document.getElementById('comment-list').innerHTML += '
  • ' + '' + '' + '
    ' + '' + data.user.login + ' 评论于 ' + '' + data.created_at + '' + '
    ' + '
    ' + data.body_html + '
    '; 470 | comment.reaction.getNum('comment', data.id); 471 | this.item.push(comment); 472 | }, 473 | checkIsLogin: function() { 474 | var comment = this; 475 | if (window.localStorage.access_token != undefined) { 476 | this.login = true; 477 | } 478 | var avatar = document.getElementById('avatar'); 479 | if (this.login == true) { 480 | $.ajax({ 481 | type: "get", 482 | async: false, 483 | headers: { 484 | Authorization: 'token ' + window.localStorage.access_token, 485 | Accept: 'application/vnd.github.squirrel-girl-preview+json' 486 | }, 487 | url: 'https://api.github.com/user', 488 | success: function(data) { 489 | window.localStorage.setItem('user_avatar_url', data.avatar_url); 490 | window.localStorage.setItem('user_url', data.html_url); 491 | window.localStorage.setItem('name', data.login); 492 | avatar.innerHTML = '' + ''; 493 | window.localStorage.setItem('authorize', btoa(data.login + ':' + window.localStorage.access_token)); 494 | }, 495 | error: function() { 496 | console.log("用户信息过期,退出登录状态"); 497 | comment.logout(); 498 | } 499 | }); 500 | } else { 501 | avatar.innerHTML = '' + '' + ''; 502 | document.getElementById('gitment-avatar').onclick = function() { 503 | comment.log(); 504 | } 505 | } 506 | }, 507 | preview: function() { 508 | $('#editComment').removeClass('gitment-selected'); 509 | $('#preview').addClass('gitment-selected'); 510 | $('.gitment-editor-write-field').addClass('gitment-hidden'); 511 | $('.gitment-editor-preview-field').removeClass('gitment-hidden'); 512 | var preview_content = document.getElementById('preview-content'); 513 | var comment_input = document.getElementById('comment-input').value; 514 | if (comment_input == "") { 515 | preview_content.innerHTML = '(没有预览)'; 516 | } else { 517 | preview_content.innerHTML = '预览加载中'; 518 | $.ajax({ 519 | type: "post", 520 | url: 'https://api.github.com/markdown', 521 | headers: { 522 | Accept: 'text/html, application/vnd.github.squirrel-girl-preview, application/vnd.github.html+json, application/x-www-form-urlencoded', 523 | 'Content-Type': 'text/html' 524 | }, 525 | data: JSON.stringify({ 526 | mode: 'gfm', 527 | text: comment_input 528 | }), 529 | dataType: "text/html", 530 | success: function(message) { 531 | preview_content.innerHTML = message.responseText; 532 | }, 533 | error: function(message) { 534 | preview_content.innerHTML = message.responseText; 535 | } 536 | }); 537 | } 538 | }, 539 | edit: function() { 540 | $('#editComment').addClass('gitment-selected'); 541 | $('#preview').removeClass('gitment-selected'); 542 | $('.gitment-editor-write-field').removeClass('gitment-hidden'); 543 | $('.gitment-editor-preview-field').addClass('gitment-hidden'); 544 | }, 545 | log: function() { 546 | window.location.href = 'https://github.com/login/oauth/authorize?client_id=' + config.client_id + '&scope=public_repo&state=' + window.location.href; 547 | }, 548 | logout: function() { 549 | this.login = false; 550 | window.localStorage.clear(); 551 | this.init(); 552 | } 553 | } 554 | 555 | var Article = function() { 556 | this.comments = new Comment(); 557 | this.page = new Pages(); 558 | this.reaction = new Reaction(); 559 | this.comment_url = ""; 560 | } 561 | 562 | Article.prototype = { 563 | init: function() { 564 | var article = this; 565 | if (self.options.token != undefined && self.options.token != null) { 566 | window.localStorage.clear(); 567 | window.localStorage.setItem("access_token", self.options.token); 568 | history.replaceState(null, config.title, 'content.html?id=' + self.options.id); 569 | } 570 | article.comment_url = 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/issues/' + self.options.id + '/comments'; 571 | article.page.getNum(article.comment_url); 572 | $.ajax({ 573 | type: 'get', 574 | headers: { 575 | Accept: 'application/vnd.github.squirrel-girl-preview, application/vnd.github.html+json, application/x-www-form-urlencoded', 576 | }, 577 | url: 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/issues/' + self.options.id, 578 | success: function(data) { 579 | document.getElementById('title').innerHTML = data.title; 580 | document.getElementsByTagName("title")[0].innerText = data.title + "-" + config.title; 581 | data.created_at = self.utc2localTime(data.created_at); 582 | document.getElementById('instruction').innerHTML = data.created_at; 583 | document.getElementById('content').innerHTML = data.body_html; 584 | var labels = document.getElementById('labels'); 585 | for (var i in data.labels) { 586 | labels.innerHTML += '# ' + data.labels[i].name + ''; 587 | } 588 | labels.innerHTML += '
    '; 589 | article.comments.init(); 590 | article.reaction.getNum('issue', self.options.id); 591 | } 592 | }); 593 | } 594 | } 595 | 596 | var Issue = function() { 597 | this.issue_url = ''; 598 | this.issue_perpage_url = ''; 599 | this.issue_search_url = ''; 600 | this.author = ''; 601 | this.creator = '', 602 | this.state = ''; 603 | this.page = new Pages(); 604 | } 605 | 606 | Issue.prototype = { 607 | getTags: function() { 608 | $.ajax({ 609 | type: 'get', 610 | url: 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/labels', 611 | success: function(data) { 612 | for (var i in data) { 613 | document.getElementById('tags').innerHTML += '' + data[i].name + ''; 614 | } 615 | }, 616 | }); 617 | }, 618 | addItem: function(data) { 619 | document.getElementById('issue-list').innerHTML = ''; 620 | for (var i in data) { 621 | var labels_content = ''; 622 | for (var j in data[i].labels) { 623 | labels_content += '
  • ' + data[i].labels[j].name + '
  • '; 624 | } 625 | data[i].body = data[i].body.replace(/<.*?>/g, ""); 626 | data[i].created_at = self.utc2localTime(data[i].created_at); 627 | document.getElementById('issue-list').innerHTML += '
  • ' + data[i].created_at + '

    ' + data[i].title + '

    ' + data[i].body + '

    ' + '
  • '; 628 | } 629 | }, 630 | show: function(request_url) { 631 | var issue = this; 632 | $.ajax({ 633 | type: 'get', 634 | url: request_url + 'page=' + self.options.page + '&per_page=10', 635 | success: function(data) { 636 | if (self.options.q == undefined || self.options.q == null) { 637 | if (data.length == 0) { 638 | document.getElementById('issue-list').innerHTML = '这个人很勤快但这里什么都还没写~'; 639 | $('.footer').css('position', 'absolute'); 640 | } else { 641 | issue.addItem(data); 642 | } 643 | } else { 644 | if (data.items.length == 0) { 645 | window.location.href = '404.html'; 646 | } else { 647 | issue.addItem(data.items); 648 | } 649 | var html = document.getElementById('issue-list').innerHTML; 650 | var newHtml; 651 | if(self.options.q != '') 652 | newHtml = html.replaceAll(self.options.q, '' + self.options.q + ''); 653 | else 654 | newHtml = html; 655 | document.getElementById('issue-list').innerHTML = newHtml; 656 | } 657 | } 658 | }); 659 | }, 660 | init: function() { 661 | if(config.filter.creator != undefined && config.filter.creator != null) { 662 | if(config.filter.creator == 'all') { 663 | this.author = ''; 664 | this.creator = ''; 665 | } else { 666 | var authors= new Array(); 667 | authors = config.filter.creator.split(","); 668 | for(var i in authors) { 669 | this.author += 'author:' + authors[i] + '+'; 670 | this.creator += 'creator=' + authors[i] + '&'; 671 | } 672 | } 673 | } else { 674 | this.author = ''; 675 | this.creator = ''; 676 | } 677 | if(config.filter.state != undefined && config.filter.state != null) { 678 | this.state = config.filter.state; 679 | } else { 680 | this.state = 'all'; 681 | } 682 | if (self.options.label == undefined) { 683 | if (self.options.q == undefined) { 684 | this.issue_url = 'https://api.github.com/repos/' + config.name + '/' + config.repo; 685 | this.issue_perpage_url = 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/issues?' + this.creator + 'state=' + this.state + '&'; 686 | } else { 687 | this.search(self.options.q); 688 | } 689 | } else { 690 | this.issue_url = 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/issues?' + this.creator + 'labels=' + self.options.label + '&state=' + this.state; 691 | this.issue_perpage_url = 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/issues?' + this.creator + 'labels=' + self.options.label + '&state=' + this.state + '&'; 692 | document.getElementById('title').innerHTML = self.options.label; 693 | $.ajax({ 694 | type: 'get', 695 | headers: { 696 | Accept: 'application/vnd.github.symmetra-preview+json', 697 | }, 698 | url: 'https://api.github.com/repos/' + config.name + '/' + config.repo + '/labels/' + self.options.label, 699 | success: function(data) { 700 | document.getElementById('instruction').innerHTML = data.description; 701 | } 702 | }); 703 | } 704 | this.page.getNum(this.issue_url); 705 | this.show(this.issue_perpage_url); 706 | this.getTags(); 707 | }, 708 | search: function(search) { 709 | search = encodeURI(search); 710 | this.issue_url = 'https://api.github.com/search/issues?q=' + search + ' ' + this.author + 'in:title,body+repo:' + config.name + '/' + config.repo + '+state:' + this.state; 711 | this.issue_perpage_url = 'https://api.github.com/search/issues?q=' + search + ' ' + this.author + 'in:title,body+repo:' + config.name + '/' + config.repo + '+state:' + this.state + '&'; 712 | } 713 | } 714 | 715 | var Buttons = function() {} 716 | 717 | Buttons.prototype = { 718 | getByClass: function(Parent, Class){ 719 | var result=[]; 720 | var ele=Parent.getElementsByTagName('*'); 721 | for(var i=0;i= 0.6 * document.documentElement.clientHeight) { 778 | $('.Totop').css('opacity', 1); 779 | } else { 780 | $('.Totop').css('opacity', 0); 781 | } 782 | } 783 | } 784 | } 785 | 786 | self.init = function() { 787 | self.info = new Info(); 788 | self.info.init(); 789 | if (self.options.id != null && self.options.id != undefined) { 790 | self.content = new Article(); 791 | self.content.init(); 792 | } else { 793 | self.content = new Issue(); 794 | self.content.init(); 795 | } 796 | self.menu = new Menu(); 797 | self.menu.show(); 798 | self.footer = new Footer(); 799 | self.footer.show(); 800 | self.button = new Buttons(); 801 | self.button.init(); 802 | } 803 | 804 | console.log('\n' + ' %c Gitblog' + ' %c https://github.com/imuncle/gitblog \n', 'color: #fadfa3; background: #030307; padding:5px 0;', 'background: #fadfa3; padding:5px 0;'); 805 | } 806 | 807 | $.ajax({ 808 | type: 'get', 809 | headers: { 810 | Accept: 'application/json', 811 | }, 812 | url: 'config.json', 813 | success: function(data) { 814 | new gitblog(data).init(); 815 | } 816 | }); --------------------------------------------------------------------------------